As far as I know, 'happens-before' states that changes made inside synchronized are visible to next thread, synchronizing on the same lock.
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();
}
});
}
Isn't it redundant?
Synchronization makes two different guarantees in Java: visibility and atomicity. Making the variable volatile
guarantees that the JVM will ensure visibility of writes properly follow "happens-before", but does not guarantee that the check-then-act within the synchronized block is atomic.
Without the guarantee of atomicity, thread interleaving on that sequence of if (closed) return; closed = true;
could result in some synchronization issues.
If the variable is always accessed from within synchronized blocks on the same monitor, the volatile
is not necessary, but might have some other minor performance impact.