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

Java 中 synchronized/volatile 变量可见性影响的程度是多少

Java 中 synchronized/volatile 变量可见性影响的程度是多少

月关宝盒 2023-05-24 15:57:43
根据“Java Concurrency in Practice”:当 B 执行由同一锁保护的同步块时,A 在同步块中或之前所做的一切对 B 都是可见的和volatile 变量的可见性影响超出了 volatile 变量本身的值。当线程 A 写入一个 volatile 变量,随后线程 B 读取同一个变量时,在写入 volatile 变量之前对 A 可见的所有变量的值在读取 volatile 变量后对 B 可见我不清楚的是一切和所有变量意味着什么?它真的意味着一切吗?如果我们有这样一个类:class MyClassA{  int a;  int[] array = new int[10];  MyClassB myClass; // a class with similar properties  void notSyncronizedMethod(){      // do something with a, array[3], myClass.a, myClass.array[3]  }  syncronized void syncronizedMethodA(){      // update value of a, array[3], myClass.a, myClass.array[3]  }  syncronized void syncronizedMethodB(){      // do something with a, array[3], myClass.a, myClass.array[3]  }}如果我们syncronizedMethodA()在一个线程中调用然后在另一个线程中调用syncronizedMethodB()or notSyncronizedMethod(),假设时间顺序是严格保证的,将调用syncronizedMethodB()并notSyncronizedMethod()使用由 设置的最新变量值syncronizedMethodA()。我确定 a 的值对于 是可以的syncronizedMethodB(),但是像 array[3]、myClass.a 甚至 myClass.myClass.array[3] 这样的引用类型的元素呢?notSyncronizedMethod()通过同步方法更新值怎么样?
查看完整描述

1 回答

?
倚天杖

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

为了弄清楚提供了哪些可见性保证,您需要更好地理解 Java 内存模型,更具体地说,在 JMM 的上下文中 happens-before 意味着什么。JMM 将发生的事情描述为actions,例如,正常的读写、volatile 读写、锁定、解锁等。

JMM 中有一些规则确定一个动作何时先于另一个动作发生。与您的情况相关的规则如下:

单线程规则:在给定线程中,如果 A 在程序顺序中先于 B,则操作 A 发生在操作 B 之前。

监视器锁定规则(同步):给定监视器的解锁发生在同一监视器上的后续锁定之前。

重要的是要知道happens-before是传递性的,即如果 hb(a, b) 和 hb(b, c),则 hb(a, c)。

在您的示例中,一个线程在退出时释放监视器syncronizedMethodA(),而另一个线程随后在进入时获取监视器syncronizedMethodB()。那是一种先发生后关系。由于 HB 是可传递的,因此执行的操作syncronizedMethodA()对于随后进入的任何线程都是可见的syncronizedMethodB()

另一方面,在释放监视器syncronizedMethodA()和由另一个线程执行的后续操作之间不存在先行关系notSynchronizedMethod()。因此,无法保证写入syncronizedMethodA()对另一个线程的读取可见notSynchronizedMethod()


查看完整回答
反对 回复 2023-05-24
  • 1 回答
  • 0 关注
  • 110 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信