2013-01-13 45 views
0

当java线程彼此通信但不需要显式同步(因此不需要调用同步对象来同步执行)时,最佳实践是什么确保相关线程的正确可见性?Java线程可见性 - 没有显式同步的最佳可见性实践

例如:

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); 
      } 

    } 
} 

如果我没有记错的话,有一个潜在的可见性问题的处理程序“处理”方法调用传递一些构造对象,那么可能不会显示在接收有道线程(陈旧的值,例如),对吗?如果是,如何强制查看而不使用同步?

谢谢。

+0

不要显式扩展Thread。在围绕它们开始线程之前,始终创建对象,并且在构建时不会出现多线程问题。 –

回答

0

不要害怕同步,如果同步块很小且很快,在你的情况下是这样,锁定解锁不会引起任何问题。

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

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

+0

是的,这是关于参数。 – xSNRG

4

应该可以使用volatile修饰符,不过我建议你使用AtomicReference

此外,如果你传递一个对象,这是不可改变的 - 然后就会出现一点问题都没有,因为最后的字段保证在构造函数结束执行前被初始化。

+0

你的意思是让内部字段“最终”?不,情况并非如此。感谢使用AtomicReference的提示。 – xSNRG

+0

AtomicReference只是一个volatile变量的包装。如果唯一的担心是能见度,那么挥发性就足够了(稍微简单一些)。 – assylias

+0

@assylias你错了,它不仅仅是一个“包装”,它提供了CAS支持。 – jdevelop