[英]Happens-before and volatile variable
以下只是JMM的三个“先发生”规则。 我没有列出其他规则,因为我的问题仅与这三个规则有关。
问题
第一个规则问题 -假设两个线程A和B具有同步的代码块。 第一条规则是否意味着即使未将变量声明为volatile,线程A的同步块中设置的任何变量对于线程B的同步块中的代码也将可见?
第二条规则问题 -假设一个线程A启动了一个线程B。第二条规则是否意味着即使在该变量未声明为volatile的情况下,调用start()之前在父线程中设置的任何变量对线程B也是可见的?
第三条规则问题 -假设一个线程A中断了一个线程B。第三条规则是否意味着在检测到中断后,线程A在线程A之前设置的任何变量在线程B之前对线程B都是可见的,即使该变量未声明为挥发性?
最后,还有一个问题:
内存一致性影响:与其他并发集合一样,在将对象放入BlockingQueue之前,在>线程中执行的操作要先于在另一个线程中的BlockingQueue中访问或删除该元素之后的操作。
这是否意味着在将对象从队列中出队后,线程A中在将对象放入队列中之前在线程A中设置的任何变量对于线程B都是可见的,即使该变量未声明为volatile也不行?
基本上通过上面的问题,我试图了解在这些事件之后是否发生了内存刷新,从而在这些情况下不需要将变量声明为volatile。
第一个规则问题-假设两个线程A和B具有同步的代码块。
线程不必代码。 线程执行代码。
第一条规则是否意味着即使未将变量声明为volatile,线程A的同步块中设置的任何变量对于线程B的同步块中的代码也将可见?
是的,假设我们有:
private int i;
private final Object lock = new Object();
void foobar(...) {
...
synchronized(lock) {
i = ...;
}
}
int getI() {
synchronized(lock) {
return i;
}
}
如果线程A调用foobar()
,然后线程B随后调用getI()
,则线程B将获得i
的新值。
但是请注意! 我上面的示例没有提供任何方法来证明哪个呼叫最先发生。 如果您的程序依赖于以特定顺序发生的那些调用,那么它不仅需要互斥锁:它还需要一些方法来使线程B wait()
使线程A执行更新。
第二条规则问题-假设一个线程A启动了一个线程B。第二条规则是否意味着即使在该变量未声明为volatile的情况下,调用start()之前在父线程中设置的任何变量对线程B也是可见的?
是的,就是这个意思。
第三条规则问题...
再来一次
- ... BlockingQueue ...
再来一次
通过上述问题,我试图了解在这些事件之后是否发生了内存刷新,从而...
甚至不要考虑“内存刷新”。 那不是Java语言的一部分:如果发生这种情况,那是实现细节,除非您正在实现 JVM,否则不必担心。
您唯一需要担心的概念是“发生之前”。
只要JLS说A 发生在 B 之前 ,就意味着如果A发生在线程1中,而B发生在线程2中,并且您可以实时证明 A确实确实发生在B之前,那么任何由保证A发生之前的线程1在B发生之后在线程2中可见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.