虚拟机系列之 Java内存模型与线程
Java内存模型与线程
Java内存模型与线程
1 概述
计算机的运算能力强大,且计算机的运算速度与它的存储和通讯子系统速度的差距太大,大部分时间都花在了磁盘I/O,网络通讯和数据库访问上。衡量一个服务性能的高低好坏,每秒事务处理数(TPS)是最重要的指标之一。
2 硬件的效率与一致性
1)基于高速缓存的存储交互解决了处理器与内存的速度矛盾,但是引入了缓存一致性的问题。
2)为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行优化,因此如果存在一个计算任务以来另外一个计算任务的中间结果,那么其顺序性不能靠代码的先后顺序来保证。
3 Java内存模型
Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果。
1)主内存与工作内存
JMM规定了所有变量(指会被共享的变量)都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间也无法直接访问对方工作内存中的变量。
2)内存间交互操作
注:如果要把一个变量从主内存复制到工作内存,就要按顺序执行read,load操作;如果要把变量从工作内存同步回主内存,就要按顺序执行store,write。顺序不代表连续。
3)volatile
第一是保证了此变量对所有线程的可见性,指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。
一致性但操作并非原子操作,所以并发下不安全,仍然要通过加锁保证原子性。
第二是禁止指令重排序优化,普通的变量并不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。
以下例子太神奇了!!!
volatile的特殊规则的数显:
(第三条没看懂…)
4)对于long 和double型变量的特殊规则
5)原子性、可见性与有序性
6)先行发生原则
如果不是按照以上规则,则虚拟机可以对它们随意排序。
4 Java与线程
1)线程的实现
1 内核线程实现
2 用户线程实现
3 混合实现
2)Java线程调度
协同式和抢占式
协同式:切换操作对线程自己可知,所以没有什么线程同步的问题,然而线程执行时间不可控制。
抢占式:线程切换不由线程本身来决定,但是执行时间可控。