Java线程可见性 - 没有显式同步的可见性的最佳实践

时间:2013-01-13 17:54:02

标签: java multithreading visibility

让java Threads相互通信,但不需要显式同步(因此不需要在对象上调用synchronize来同步执行),确保所涉及线程之间的正确可见性的最佳做法是什么?

例如:

class B extends Thread {
     ...
     A instanceOfA = ...;

     B(){
          instanceOfA.registerHandler(new Handler(){
               @Override
               handle(SomeObjectToBeVisibile o){
                  ...
               }
          });
     }
}

class A extends Thread {
     ...
     void registerSomeHandlerMethod(HandlerMethod handler){...}

     void executeHandlers(){
          for(each registered handler){
              handler.handle(instanceOfSomeObjectToBeVisible); 
          }

     }
}

如果我没有弄错,那么处理程序“handle”方法调用有一个潜在的可见性问题,它会传递一些构造的对象,然后在接收线程中可能看不到正确的方式(过时的值,例如),对吗?如果是,如何在不使用synchronized的情况下强制可见性?

感谢。

2 个答案:

答案 0 :(得分:4)

应该可以使用volatile修饰符,但我建议使用AtomicReference

此外,如果你传递的是一个不可变的对象 - 那么根本不会出现任何问题,因为在构造函数结束执行之前,保证最终字段被初始化。

答案 1 :(得分:0)

不要害怕同步,如果同步块小又快,这在你的情况下是正确的,锁定解锁不会导致任何问题。

您可以使用“无锁”并发数据结构,例如ConcurrentLinkedQueue。 (对你的情况来说,速度不会太快)

编辑:看起来你担心传递给handle()的参数的可见性,而不是处理程序本身。