java - volatile 变量和非 volatile 重新排序/可见性

标签 java concurrency jvm visibility volatile

所以我认为我对这些东西已经足够了解了,直到我读到一些让我怀疑我对这个主题的知识的东西。我几乎可以肯定这本书是不正确的,但也想问问社区。

PS: 没看过书的勘误表,所以很可能被披露为一个错误。

一个简化的例子:

public class VolatileMain {

private volatile int a = 0;
private String text = "";

public static void main(String[] args) throws Exception {

    VolatileMain vm = new VolatileMain();

    Thread writer = new Thread() {

        @Override
        public void run() {
            System.out.println("Running thread " + Thread.currentThread().getName());
            vm.text = "hello world";
            vm.a = 5;
        }
    };

    writer.start();
    writer.join();

    System.out.println("Running thread " + Thread.currentThread().getName());
    System.out.println(vm.a);
    System.out.println(vm.text);

   }

}

所以给出这个例子是否正确假设线程编写器对“文本”的写入保证对读取它的任何其他线程可见?

作者似乎在利用变量“a”的可变语义,并确保在刷新“a”时也会刷新对“text”的写入,这是保证吗?

我不认为是,但我自己的快速测试(上图)恰恰相反

你的想法。

最佳答案

is it correct to assume that the write to "text" by Thread writer is guaranteed to be visible by any other thread that reads it?

没有。但它保证在读取 text 之前读取 a 的任何其他线程可见,就像您的示例一样:

  • text 的写入发生在 writer 线程中写入 a 之前
  • writer 中a 的写入发生在主线程中a 的读取之前
  • happens-before 关系是可传递的
  • 因此 text 的写入发生在 a 的读取之前。

关于java - volatile 变量和非 volatile 重新排序/可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33472242/

相关文章:

java - 检测使用 "dangerous"跨不同 Java 实现或操作系统使用的功能的技术?

java - 内存不足 : metaspace with wildfly and groovy/jasper

java - Sun 的 javac 产生的奇怪异常表条目

java - 链表或递归调用 HashMap

c# - ASP.NET 中的并发线程和锁

concurrency - 使用 Actor 发送+处理多条消息

multithreading - Java 8 ConcurrentHashMap 合并与 computeIfAbsent

java - Project Reactor - 使用 defer() 使方法可重试

java - 即使值存在,也无法单独从 Redis 加载值

java - 如何在 Jackson JSON(反)序列化中使用自定义键类型自定义序列化或转换 Map 属性?