Я бы предложил использовать другой объект в качестве блокировки, чтобы гарантировать, что класс блокируется только при обращении к obj
:
public class Test
{
private final Object lock = new Object();
private Object obj;
public void init()
{
service.registerListener(new InnerTest());
}
public void readObj()
{
synchronized(lock){
// read obj here
}
}
private class InnerTest implements Listener
{
public void updateObj()
{
synchronized(Test.this.lock){
Test.this.obj = new Object();
// change the obj
}
}
}
}
Затем используйте эту блокировку во всех методах, которым необходим постоянный доступ к obj
. В вашем текущем примере методы readObj
и updateObj
.
Также, как указано в комментариях, использование synchronized
на уровне метода в вашем классе InnerTest
не будет работать так, как вы, вероятно, предполагали. Это потому, что синхронизированные методы будут использовать блок synchronized
в переменной this
. Который просто блокирует ваш InnerTest
класс. Но не внешний Test
класс.