一个输出语句引起的线程问题思考

 

1、问题抛出:

这是一个网友在写线程代码时无意间发现的一个问题,线程不能正常停止。

那为什么输出语句在while里和外会影响到线程的正常停止呢?

 

2、问题猜想:

当我看到这个问题的时候,首先想到的是多线程内存可见性引起的问题。为了证明我的猜想,将stop变量声明为volatile(用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新)。于是线程正常终止了。

3、继续猜想:

为什么加上输出也能正常终止呢? 难道是因为输出引起了cpu缓存的刷新操作?

于是我打开 System.out.println()的源码,果然在println方法上面有一个同步关键字。

20100202_ntwR.jpg
那么问题就已明显,正是因为同步关键字引起的cpu缓存同步主内存。

synchronized 用于确保写线程更新变量后,读线程再访问该 变量时可以读取到该变量最新的值。

 

4、总结:

1、java层面

在CPU结构上就是load buffer和store buffer在进入同步块的时候会被刷到缓存。

在boolean stop关键字上加volatile和使用PrintWriter.pringln中同步块的原理是一样的,区别在于两种方式的差异。

同步块是通过对象内置锁来通信,就是说不到同步块收不到并发信息

而volatile通过lock关键字,只要通过读写都能收到

2、cpu层面

加入一个循环变量被放到寄存器里面了,并且构造了一个高速死循环,你从另一个线程里面去改变一个内存里面的值,确实不会影响到这个寄存器里面的变量
 

比如一个变量名字为a,这个a刚开始存储在内存里面
但是作为一个循环判断变量的时候,很可能就被编译器优化一下放到CPU里面的寄存器内部了

而CPU现在是多个核心的
一个核心基于寄存器里面的值去做死循环,另一个核心如果不是刻意通过什么指令去找到这个核心的寄存器操作,估计是没办法打断它了

 

5、说明

才疏学浅,如有误解,欢迎打脸,哈!

 

 

转载于:https://my.oschina.net/yangshj/blog/734464

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值