java.io.FileInputStream 仅从同步块内部访问私有易失性变量 'closed'。为什么?
java.io.FileInputStream accesses private volatile variable 'closed' only from inside synchronized block. Why?
据我所知,'happens-before' 声明在 synchronized 内部所做的更改对下一个线程可见,在同一个锁上同步。
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();
}
});
}
这不是多余的吗?
同步在 Java 中提供两种不同的保证:可见性和原子性。使变量 volatile
保证 JVM 将确保写入的可见性正确遵循 "happens-before",但不保证同步块中的先检查后操作是原子的。
如果没有原子性保证,if (closed) return; closed = true;
序列上的线程交错可能会导致一些同步问题。
如果始终从同一监视器上的同步块内访问变量,则 volatile
不是必需的,但可能会对性能产生其他一些较小的影响。
本机方法可能会访问该变量。您需要查看 JDK.
的本机源代码
根据 Memory Consistency Properties 的第二个要点,volatile
关键字是多余的。
An unlock (synchronized block or method exit) of a monitor
happens-before every subsequent lock (synchronized block or method
entry) of that same monitor. And because the happens-before relation
is transitive, all actions of a thread prior to unlocking
happen-before all actions subsequent to any thread locking that
monitor.
据我所知,'happens-before' 声明在 synchronized 内部所做的更改对下一个线程可见,在同一个锁上同步。
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();
}
});
}
这不是多余的吗?
同步在 Java 中提供两种不同的保证:可见性和原子性。使变量 volatile
保证 JVM 将确保写入的可见性正确遵循 "happens-before",但不保证同步块中的先检查后操作是原子的。
如果没有原子性保证,if (closed) return; closed = true;
序列上的线程交错可能会导致一些同步问题。
如果始终从同一监视器上的同步块内访问变量,则 volatile
不是必需的,但可能会对性能产生其他一些较小的影响。
本机方法可能会访问该变量。您需要查看 JDK.
的本机源代码根据 Memory Consistency Properties 的第二个要点,volatile
关键字是多余的。
An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.