为了账号安全,请及时绑定邮箱和手机立即绑定

是否可以使用可见性保证而不是完全锁定来以线程安全的方式访问共享状态?

是否可以使用可见性保证而不是完全锁定来以线程安全的方式访问共享状态?

HUWWW 2022-12-28 14:39:17
Java Concurrency in Practice 声明如下:当线程 A 执行一个同步块,随后线程 B 进入一个由同一个锁保护的同步块时,在释放锁之前对A 可见的变量值保证在获取锁时对 B 可见。换句话说,当 B 执行由同一锁保护的同步块时,A 在同步块中或之前所做的一切对 B 都是可见的。没有同步,就没有这样的保证。同样的逻辑适用于 volatile 变量:volatile 变量的可见性影响超出了 volatile 变量本身的值。当线程 A 写入一个 volatile 变量,随后线程 B 读取同一个变量时,在写入 volatile 变量之前对 A 可见的所有变量的值在读取该 volatile 变量后对 B 可见。从描述中可以清楚地看出,当您需要访问某些共享状态时,您可以使用这种可见性效果来实际替换(或限制使用)传统锁。在图中的示例中,您可以看到线程 B 可以安全地读取变量y,即使它在同步块外的线程 A 中发生了更改。因此,当您在线程上锁定之前更改某些共享状态时使用它是否安全visibility guarantee,然后获取锁定,做某事(或者什么都不做,我猜),释放锁然后在另一个线程中获得相同的锁锁定,释放它,然后安全地从第一个线程中更新的共享变量中读取最新值?
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

引用语句中有一个关键部分:

volatile 变量的可见性影响超出了 volatile 变量本身的值。当线程 A 写入一个 volatile 变量,随后线程 B 读取同一个变量时,在写入 volatile 变量之前对 A 可见的所有变量的值在读取 volatile 变量后对 B 可见。

虽然这显然是正确的,但您在这里得到了关于 A 写先于 B 阅读的条件。然而,如果不锁定,就无法保证读/写的顺序——这就是重点。

所以你不能用 volatiles 替换每个同步,因为它不会产生相同的结果。


查看完整回答
反对 回复 2022-12-28
?
白板的微信

TA贡献1883条经验 获得超3个赞

是的,您可以visibility guarantee通过使用或任一形式的锁定以描述的方式获得,但volatile仅此而已。具体来说,您不会获得相互访问和原子性。synchronized

另请参阅 JLS中有关 JVM的内存模型和happens-before关系的部分,以获得更多细节和深度。


查看完整回答
反对 回复 2022-12-28
  • 2 回答
  • 0 关注
  • 107 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号