让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的情况下强制可见性?
感谢。
答案 0 :(得分:4)
应该可以使用volatile修饰符,但我建议使用AtomicReference
此外,如果你传递的是一个不可变的对象 - 那么根本不会出现任何问题,因为在构造函数结束执行之前,保证最终字段被初始化。
答案 1 :(得分:0)
不要害怕同步,如果同步块小又快,这在你的情况下是正确的,锁定解锁不会导致任何问题。
您可以使用“无锁”并发数据结构,例如ConcurrentLinkedQueue。 (对你的情况来说,速度不会太快)
编辑:看起来你担心传递给handle()
的参数的可见性,而不是处理程序本身。