It is very difficult to guarantee correct operation when such synchronization is used. It may be possible to improve such code, for example, by controlling access using a synchronized wrapper class or by synchronizing on a field.
Example:
void bar() { final Object lock = new Object(); synchronized (lock) { } }