我有两个主题:
主题:1
a = 1;
x = b;
Run Code Online (Sandbox Code Playgroud)
主题:2
b = 1
y = a
Run Code Online (Sandbox Code Playgroud)
这里a和b被声明为volatile.我不明白在a = 1之间如何创建"before-before"边缘; 和y = a; 在x = b之间; 和b = 1;
我知道通过使用volatile变量可以防止从线程缓存中读取过时值.但是,在订购之前,如何确保变量发生变化.
具体来说,我不明白这一点:
对每个后续读取相同字段之前发生对易失性字段的写入.
锄头有用吗?
Jon*_*eet 16
对每个后续读取相同字段之前发生对易失性字段的写入.
这里的重要词是"后续".
以下是Java语言规范17.4.4同步顺序的相关部分:
每次执行都有一个同步顺序.同步顺序是执行的所有同步动作的总顺序.对于每个线程t,t中同步动作(第17.4.2节)的同步顺序与t的程序顺序(第17.4.3节)一致.同步动作引发与动作的同步关系,定义如下:
- [...]
- 对volatile变量(第8.3.1.4节)的写入v与任何线程的v的所有后续读取同步(其中后续根据同步顺序定义).
请注意最后一部分.所以它说如果你考虑程序动作的任何总排序,那么后来在总排序中而不是写入的易失性变量的任何读取都不能"错过"写入.
要进行分析,首先要列出所有可能的同步顺序。它们必须与编程顺序一致。在您的示例中,有 6 个可能的订单。
1 2 3 4 5 6
w(a) w(a) w(b) w(a) w(b) w(b)
r(b) w(b) w(a) w(b) w(a) r(a)
w(b) r(b) r(b) r(a) r(a) w(a)
r(a) r(a) r(a) r(b) r(b) r(b)
Run Code Online (Sandbox Code Playgroud)
每个订单都建立了一些发生在之前的关系。在(1)中,我们有 w(a) 发生在 r(a) 之前。在(6)中,我们有 w(b) 发生在 r(b) 之前。在(2)-(5)中,我们两者都有。
对于每个可能的 order,给定它建立的happens-before 关系,您需要分析执行以确保它执行您想要的操作。
如果这听起来太难了,那就是。在现实生活中,我们通常会用更简单的情况来限制自己,即只有一个对象被锁定/释放,或者只有一个 volatile 变量被读写。然后它不是太复杂。
| 归档时间: |
|
| 查看次数: |
5072 次 |
| 最近记录: |