据我所知,'发生在之前'声明同步内部所做的更改对下一个线程可见,并在同一个锁上同步。
private final Object closeLock = new Object();
private volatile boolean closed = false;
public void close() throws IOException {
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
if (channel != null) {
channel.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}
不是多余的吗?
答案 0 :(得分:2)
同步在Java中提供了两种不同的保证:可见性和原子性。使变量volatile
保证JVM将确保正确遵循“之前发生”的写入可见性,但不保证同步块中的check-then-act是原子的。
如果没有原子性保证,if (closed) return; closed = true;
序列上的线程交错可能会导致一些同步问题。
如果始终从同一监视器上的同步块内访问变量,则volatile
不是必需的,但可能会对性能产生轻微影响。
答案 1 :(得分:1)
该变量很可能由本机方法访问。您需要查看JDK的本机源代码。
答案 2 :(得分:1)
根据Memory Consistency Properties的第二个要点,volatile
关键字是多余的。
监视器的解锁(同步块或方法退出) 发生在每个后续锁定之前(同步块或方法) 那个监视器的入口)。并且因为发生在关系之前 是传递的,解锁之前线程的所有动作 发生之前任何线程锁定之后的所有操作 监视。