java - 字段读取同步和 volatile 之间的可见性差异

标签 java multithreading synchronization volatile thread-synchronization

我已阅读 SO 的以下文章

Difference between synchronization of field reads and volatile

这里提问者写道

the point of the synchronization is to ensure that the value of acct.balance that are read by this thread is current and that any pending writes to the fields of the object in acct.balance are also written to main memory.

最受欢迎的答案:

You are correct.

请研究这段代码:

public class VolatileTest {

    static/* volatile */boolean done = false;

    public VolatileTest() {
        synchronized (this) {

        }

    }

    public static void main(String[] args) throws Exception {
        Runnable waiter = new Runnable() {
            public void run() {
                while (!done)
                    ;
                System.out.println("Exited loop");

            }
        };
        new Thread(waiter).start();
        Thread.sleep(100); // wait for JIT compilation
        synchronized (VolatileTest.class) {
            done = true;
        }
        System.out.println("done is true ");
    }

}

在我的电脑上这个程序不会终止。

所以我认为

  1. 如果我更改 volatile 变量,我将在另一个线程中看到实际值 无处不在的优秀!
  2. 如果我用监视器“A”改变同步部分的变量,我会 仅在与监视器“A”同步的部分中查看实际值(例如在另一个线程中)

我说得对吗?

最佳答案

  1. 是的,这是真的,因为 volatile write happens-before 写入的值可以从变量中读取。
  2. 不完全是。可以保证同一监视器上的另一个同步线程将看到更新后的值,因为监视器释放发生在同一监视器被另一个线程获取。如果不获取相同的监视器,其他线程可能会看到更新后的值。你公式中的“唯一”太强了:)

关于java - 字段读取同步和 volatile 之间的可见性差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23339903/

相关文章:

php - 使我的代码异步,这样就不会永远加载

java - 编辑文本上的变量已更改监听器

Java 正则表达式缺少匹配项

c - 生产者消费者同步使用两个线程提供不正常的串行输出

python - Python 端口扫描器中的线程

python - 如何同步两个不同系统中的两个文件夹

multithreading - 如何制作原子指令

java - 从 Java 列出所有 MongoDB 数据库及其详细信息

java - 确定哪个网络接口(interface)将用于 JDK 上的给定主机名

java - 线程停止时无法结束工作流程