Java多线程(二)Java内存模型
Java 内存模型(JMM)是一种抽象的概念,并不真实存在,它描述了一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段、静态字段和构成数组对象的元素)的访问方式。JVM中的堆内存用来存储对象实例,堆内存是被所有线程共享的运行时内存区域,因此它存在可见性问题。Java内存模型定义了线程和主存间的抽象关系:线程之间的共享变量存储在主存中,每个线程有一个私有的本地内存,本地内存中存储了该线程共享变量的副本。需要注意的是本地内存是Java内存模型的一个抽象概念,并不真实存在,它涵盖了缓存、写缓冲区、寄存器等区域。Java内存模型的抽象示意图如下所示:
线程A与线程B要通信的话,要经历下面两个步骤:
- 线程A把线程A本地内存中更新过的内存共享变量刷新到主存;
- 线程B到主存中取线程A之前更新过的共享变量。
所以我们在执行下面语句:
1 | int i = 0; |
语句所在的线程会对变量i所在的缓存进行赋值操作,然后再写入主存中,而不是直接将数值0写入主存。
为了有个直观的感受,我们用一段代码来实现一下。先定义一个类VolatileDemo
,包含一个running
字段和一个stop
方法:
1 | public class VolatileDemo { |
1 | public static void main(String[] args) { |
我们在main
方法,即主线程中创建VolatileDemo
对象实例,然后新创建一个子线程,进入while
循环不断的判断running
属性。我们让主线程sleep
1000毫秒,然后执行stop
更新running
的值为false
,按正常逻辑如果running = false
的话,子线程就会执行完,打印end
,然后整个程序执行完毕。我们运行程序看一下:
发现子线程并没有打印end
,并且程序一直在运行,没有结束退出。说明主线程更新的running = false
,子线程并不知道。
示例代码已上传Github
关注我
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 droidYu!