java 在澄清/误解之前发生的不稳定事件?

3pmvbmvn  于 2023-02-18  发布在  Java
关注(0)|答案(1)|浏览(130)

“对volatile字段的写入(参见8.3.1.4节)发生在该字段的每次后续读取之前。”
所以我知道volatile字段可以用作同步,以保证线程1在写入volatile字段之前拥有的所有信息,在线程2阅读该volatile字段之后都将可见。
但是后续的写呢?行为是一样的吗?感谢任何帮助,在官方文档中找不到任何关于它的东西。
示例:

### Write -> Read

#Thread1 (Write)
xxx = "anyValue" - any variable with value before volatile
boolean volatile b = true

#Thread2 (Read)
if (b) { -> here we read volatile value
 print(xxx) -> guaranteed visibility of 'xxx' 100%, will print 100% "anyValue"
}

### Write -> Write

#Thread1 (Write)
xxx = "anyValue" - any variable with value before volatile
boolean volatile b = true;

#Thread2 (Write)
b = false; -> here we write to volatile value
print(xxx); -> guaranteed visibility of 'xxx'???, what will be printed?
7fyelxc5

7fyelxc51#

为了给予更全面的答案,我们可以从基本顺序出发,建立“之前发生”关系:
1.同步顺序:这是所有同步操作的总顺序。由于易失性写入是同步操作,因此对相同或不同变量的2个易失性写入是同步顺序的一部分。同步顺序甚至会对A的锁定和B的易失性读取进行排序,因为这是总顺序。

  1. synchronizes-with order。这是一种偏序,仅对某些同步操作进行排序。例如,释放锁并随后获取同一锁,以及写入volatile变量并随后读取该变量。因此,对不同或相同变量的2次volatile写入不按synchronizes-with order排序。
    1.程序顺序:简单的说,这是程序代码指定的顺序。2在你的例子中,两个volatiles的写操作不是按照程序顺序排序的,因为它们是由不同的线程发出的。
    现在我们进入最后一步:之前发生关系是一个序,它是程序序和同步序的并集的传递闭包。
    因此,即使这两个volatile写入是同步顺序的一部分,但它们不是同步顺序的一部分,因此,它们也不是发生前顺序的一部分,因此它们不会引发任何发生前边沿。

相关问题