前两天参加了一个电话面试,面试官问了很多问题,挑一些印象深刻的记录分享一下。其中一个问题是:Java多线程怎么保证变量的可见性?听到问题之后,我懵了……
在网上搜索学习了一下,简单概括如下:
Java中可以通过synchronized、volatile、java concurrent类来实现共享变量的可见性。
1.synchronized
synchronized 实际上是对访问修改共享变量的代码块进行加互斥锁,多个线程对synchronized代码块的访问时,某一时刻仅仅有一个线程在访问和修改代码块中的内 容(加锁),其他所有的线程等待该线程离开代码块时(释放锁)才有机会进入synchronized代码块。
所以某一个线程进入synchronized代码块前后,执行过程入如下:
a.线程获得互斥锁
b.清空工作内存
c.从主内存拷贝共享变量最新的值到工作内存成为副本
d.执行代码
e.将修改后的副本的值刷新回主内存中
f.线程释放锁
随后,其他代码在进入synchronized代码块的时候,所读取到的工作内存上共享变量的值都是上一个线程修改后的最新值。
*共享变量不可见主要有下列原因:
a.线程的交叉执行
b.重排序
c.共享变量未能及时更新
通过使用synchronized可以保证原子性(synchronized代码块内容要么不执行,要执行就保证全部执行完毕)和可见性。