Java线程可见性-无显式同步的可见性最佳实践
当java线程彼此通信,但不需要显式同步(因此无需调用对象上的同步来同步执行)时,确保相关线程之间适当可见性的最佳实践是什么 例如:Java线程可见性-无显式同步的可见性最佳实践,java,multithreading,visibility,Java,Multithreading,Visibility,当java线程彼此通信,但不需要显式同步(因此无需调用对象上的同步来同步执行)时,确保相关线程之间适当可见性的最佳实践是什么 例如: class B extends Thread { ... A instanceOfA = ...; B(){ instanceOfA.registerHandler(new Handler(){ @Override handle(SomeObjectTo
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”方法调用可能存在可见性问题,这些对象可能在接收线程中以正确的方式不可见(例如,过时的值),对吗?如果是,如何在不使用同步的情况下强制可见性
谢谢。应该可以使用挥发性修饰剂,但我建议使用
另外,如果您要传递一个不可变的对象,那么就不会出现任何问题,因为最终字段保证在构造函数结束执行之前初始化。应该可以使用易失性修饰符,但是我建议使用
另外,如果您传递的是一个不可变的对象,那么就不会出现任何问题,因为最终字段保证在构造函数结束其执行之前初始化。不要害怕同步,如果同步块小而快,这在您的情况下是正确的,那么lock unlock不会导致任何问题 您可以使用“无锁”并发数据结构,如ConcurrentLinkedQueue。(对于您的案例来说,这不会快很多)
编辑:看起来您担心的是传递给
handle()
的参数的可见性,而不是处理程序本身 不要害怕同步,如果同步块又小又快(在您的情况下也是如此),那么锁定解锁不会导致任何问题
您可以使用“无锁”并发数据结构,如ConcurrentLinkedQueue。(对于您的案例来说,这不会快很多)
编辑:看起来您担心的是传递给
handle()
的参数的可见性,而不是处理程序本身 你的意思是让内部字段成为“最终”字段?不,事实并非如此。感谢使用AtomicReference的提示。AtomicReference只是一个围绕易失性变量的包装器。如果唯一关心的是可见性,那么volatile就足够了,而且(稍微)简单了。@assylias你错了,它不仅仅是一个“包装器”,它还提供了CAS支持。@jdevelop我知道-我的意思是:如果唯一关心的是可见性,就不需要CAS操作,volatile语义就足够了。@assylias啊,好,但我认为这就像数组/集合一样——使用后者,因为它会在需要时为您提供额外的功能:)您的意思是将内部字段设置为“final”?不,事实并非如此。感谢使用AtomicReference的提示。AtomicReference只是一个围绕易失性变量的包装器。如果唯一关心的是可见性,那么volatile就足够了,而且(稍微)简单了。@assylias你错了,它不仅仅是一个“包装器”,它还提供了CAS支持。@jdevelop我知道-我的意思是:如果唯一关心的是可见性,就不需要CAS操作,volatile语义就足够了。@assylias啊,好,但我认为它就像数组/集合一样——使用后者,因为它会在需要时为您提供额外的功能:)是的,它是关于参数的。是的,它是关于参数的。不要显式扩展线程。始终在围绕对象启动线程之前创建对象,这样在构建过程中就不会出现多线程问题。不要显式扩展线程。始终在围绕对象启动线程之前创建对象,这样在构建过程中就不会出现多线程问题。