有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程java。伊奥。FileInputStream仅从同步块内部访问私有易失性变量“closed”。为什么?

据我所知,“在之前发生”表示在同步内所做的更改对下一个线程可见,在同一个锁上同步

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();
       }
    });
}

这不是多余的吗


共 (2) 个答案

  1. # 1 楼答案

    在Java中,同步有两种不同的保证:可见性和原子性。使变量volatile可以保证JVM将确保写入的可见性正确地遵循“之前发生的”,但不能保证随后在同步块内执行的检查是原子的

    如果不保证原子性,线程在if (closed) return; closed = true;序列上的交错可能会导致一些同步问题

    如果总是从同一监视器上的同步块内访问变量,则volatile不是必需的,但可能会对性能产生其他一些较小的影响

  2. # 2 楼答案

    根据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.