线程安全访问私有字段

时间:2018-07-03 08:01:57

标签: java multithreading concurrency thread-safety

所以我有以下情况(无法共享实际代码,但是会是这样):

public class Test
{
   private Object obj;

   public void init()
   {
       service.registerListener(new InnerTest());
   }

   public void readObj()
   {
       // read obj here
   }

   private class InnerTest implements Listener
   {
       public synchronized void updateObj()
       {
           Test.this.obj = new Object();
           // change the obj
       }
   }
}

InnerTest类在服务中注册为侦听器。该服务正在一个线程中运行,因此从另一个线程进行对readObj()的调用,因此,我的问题是确保obj的一致性是否足以使UpdateObj()方法同步?

1 个答案:

答案 0 :(得分:3)

我建议使用另一个对象作为锁,以确保该类仅在访问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进行一致访问的所有方法中使用该锁。在您当前的示例中,readObjupdateObj方法。

也如注释中所述,在synchronized类的方法级别上使用InnerTest并不会真正按照您的预期工作。也就是说,因为同步方法将在synchronized变量上使用this块。这只会阻塞您的InnerTest类。但不是外部Test类。