Java volatile关键字的问题

//线程1
boolean stop = false;
while(!stop){
doSomething();
}

//线程2
stop = true;

这段代码是很典型的一段代码,很多人在中断线程时可能都会采用这种标记办法。但是事实上,这段代码会完全运行正确么?即一定会将线程中断么?不一定,也许在大多数时候,这个代码能够把线程中断,但是也有可能会导致无法中断线程(虽然这个可能性很小,但是只要一旦发生这种情况就会造成死循环了)。

下面解释一下这段代码为何有可能导致无法中断线程。在前面已经解释过,每个线程在运行过程中都有自己的工作内存,那么线程1在运行的时候,会将stop变量的值拷贝一份放在自己的工作内存当中。

  那么当线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,那么线程1由于不知道线程2对stop变量的更改,因此还会一直循环下去。

看如上代码和描述,

这里为什么会造成死循环,即使线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,在我的思路里,线程2也会在做完其他事也会把stop变量的值更新。这样不会有死循环的问题,只是时间快慢的问题。

4个回答

如果没有volatile 做修饰stop = true;,这时其他线程对stop可能不会立马可见,但不代表永远不可见,那只是时间问题,当然这个时间对人来讲肯定很快,微妙级别的或更短
你只要线程2给stop赋了true,不管你再去做啥事线程1都会停止

zhaomin_g
_zming 回复A_A333: 是的,我已经回答了,如果没有volatile修饰,由于jvm优化,其他线程是不能立马感知变量做了修改,可能线程2都已经全部执行完了,线程1都还不知道,有了volatile会取消优化,立马刷新
大约 2 年之前 回复
A_A333
A_A333 多问个问题,是不是赋值完毕线程不负责立马刷新主存,有可能继续往下执行线程的其他语句,有volatile的话就会立即刷新主存
大约 2 年之前 回复

要保证volatile boolean stop ; 还有就是线程2 一定会执行,且不会发生异常; 其实很难保证线程没有异常发生; 所以需要加入一个hook , 将stop 改为 true

A_A333
A_A333 多问个问题,是不是赋值完毕线程不负责立马刷新主存,有可能继续往下执行线程的其他语句,有volatile的话就会立即刷新主存
大约 2 年之前 回复

其实主要讲的不是线程2不会更新stop,而是可能线程1一直没有去从主存读取stop,一直读取自己寄存器的值,就可能一直循环下去

A_A333
A_A333 回复oyljerry: 即使重排序也不会有影响的吧,上面的代码是确定线程2先触发的,然后再到线程1
大约 2 年之前 回复
oyljerry
oyljerry 不一定,可能优化
大约 2 年之前 回复
A_A333
A_A333 线程2更新了stop,线程1都应该去读的把,没有volatile修饰的话,只是时间问题而已把
大约 2 年之前 回复

并发编程 之 volatile 关键字

http://www.verejava.com/?id=1734028422785

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问