【发布时间】:2016-11-10 03:45:16
【问题描述】:
我知道您可以通过将引用写入 final 或 volatile 字段来安全地发布非线程安全对象,该字段稍后将由另一个线程读取,前提是发布时,创建的线程对象丢弃对它的引用,因此它不再干扰或不安全地观察对象在其他线程中的使用。
但是在这个例子中,没有明确的final 字段,只有final 局部变量。 如果调用者放弃了对unsafe 的引用,那么这个发布是否安全?
void publish(final Unsafe unsafe) {
mExecutor.execute(new Runnable() {
public void run() {
// do something with unsafe
}
}
}
我发现了一些问答,例如this one,表明final 局部变量被隐式“复制”到匿名类中。是不是说上面的例子就和这个等价了?
void publish(final Unsafe unsafe) {
mExecutor.execute(new Runnable() {
final Unsafe mUnsafe = unsafe;
public void run() {
// do something with mUnsafe
}
}
}
编辑澄清:
Unsafe 可以是任何东西,但是说它是这样的:
public class Unsafe {
public int x;
}
而mExecutor是任何满足Executor合约的东西。
【问题讨论】:
-
您的执行程序正在使用线程安全队列。要查看此问题,您必须在线程之间传递对象,而无需在任何地方使用适当的内存屏障。
-
@PeterLawrey
class Executor { void execute(Runnable r) { } }- 这里没有队列。但这一点可能仍然有效...... -
BTW
Unsafe是一个有单例的类,虽然你可以创建更多... -
@PeterLawrey 我不是指
sun.misc.Unsafe。为清晰起见进行了编辑。
标签: java multithreading safe-publication