java - Java内存模型如何确保所有线程看到的变量值一致?

标签 java multithreading locking synchronisation

通过詹姆斯·高斯林(James Gosling)的JLS,我碰到了这一点-

Java编程语言提供了第二个机制(除了同步之外),易失字段,它比出于某些目的而锁定更方便。

可以将字段声明为 volatile ,在这种情况下 Java内存模型确保所有线程看到变量一致值,然后作者指向this资源。

enter image description here

似乎结果r2 == 2r1 == 1是不可能的。
但是为什么呢?

考虑这样的事情不是很有意义吗?

Instruction 4 : A = 2;
Instruction 1 : r2 = A;
Instruction 2 : B = 1;
Instruction 3 : r1 = B;

其余的我也听不懂。

It may appear that the result r2 == 2 and r1 == 1 is impossible. Intuitively, either instruction 1 or instruction 3 should come first in an execution. If instruction 1 comes first, it should not be able to see the write at instruction 4. If instruction 3 comes first, it should not be able to see the write at instruction 2.

If some execution exhibited this behavior, then we would know that instruction 4 came before instruction 1, which came before instruction 2, which came before instruction 3, which came before instruction 4. This is, on the face of it, absurd.

However, compilers are allowed to reorder the instructions in either thread, when this does not affect the execution of that thread in isolation. If instruction 1 is reordered with instruction 2, as shown in the trace in Table 17.4-B, then it is easy to see how the result r2 == 2 and r1 == 1 might occur.



请举例说明。

最佳答案

这是英语写作中常见的修辞模式。一位作家说,情况可能“出现”,或者说某人“可能认为”情况是这样,他们解释了可能导致该结论的无效推理,然后继续解释了事实并非如此。案子。使用这种修辞手法,中间部分由作者认为不正确的语句组成。

您引用的部分旨在精确地解释您已经了解的内容-如果编译器不影响单线程代码,它们通常可以自由地对内存读写进行重新排序。

因此,例如,在本段中:

It may appear that the result r2 == 2 and r1 == 1 is impossible. Intuitively, either instruction 1 or instruction 3 should come first in an execution. If instruction 1 comes first, it should not be able to see the write at instruction 4. If instruction 3 comes first, it should not be able to see the write at instruction 2.



通过“可能出现”,他表示某人可能会认为,但这不是事实。然后,他继续解释为什么有人会这样想,然后解释为什么那是错误的。该作者第一个句子之后的句子被作者认为是错误的,然后他将继续解释它们是如何错误的。

关于java - Java内存模型如何确保所有线程看到的变量值一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38643595/

相关文章:

java - 在 Android 字符串中操作数据库输出

java - JPA 中 @ManytoOne 中的复合主键与链接类

ios - 如何确保 MIDI 消息以正确的顺序到达?

MySQL全文查询锁表

java - JTable中的并发问题

java - fater网页源提供者

java - 枚举真的是常量吗? enum 的数据成员不应该默认声明为 final 吗?

linux - 如果多个线程 epoll 在同一个套接字上等待怎么办?

java - 调用thread.join()时如何通知lock

java - 为什么在 Java 的 ArrayBlockingQueue 实现中在 Offer(E e) 中使用 lock() 而在 put(E e) 中使用 lockInterruptically()