一、前言
前面讲解了JVM类的一些基础,以及JVM怎么通过classLoader去加载一个类,一个类的生命周期等知识,我们至少在理论上对JVM有一个基本的认识,接下来我们看看JVM怎么实施它的并发。
二、
JAVA内存
基于高速缓存的存储很好解决了处理器与内存的矛盾,但是可能存在各自缓存数据已不一致的问题,这时候出现MSI、MESI等协议解决一致性。
2.1主内存与工作内存
java内存模型主要解决的是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中读取变量的这样的低层细节。
为了或得好的执行效率,java内存模型没有限制执行引擎使用处理器的特定寄存器会缓存来和主内存交互,没有限制即使编译器执行代码顺序。(此处主内存只是虚拟机内存的部分可以理解为堆内存,工作内存理解为栈内存)
主要的步骤如下:
2.2.1 锁定lock
-主内存,变量标识为一条线程独占状态。
2.2.2 解锁unlock
-主内存,变量释放,释放之后才可以被其他线程锁定。
2.2.3 读取read
-主内存,变量从主内存传输的工作内存。
2.2.4 载入load
-工作内存,蒋read的操作放入工作内存变量副本中。
2.2.5 使用use
-工作内存,使用变量。
2.2.6 赋值assign
-工作内存,变量赋值给其他变量。
2.2.7 存储store
-工作内存,变量传输到主内存。
2.2.8 写入write
-住内存,主内存存储。
tip:只有先read才会load,只有先store才会write,而且不能单独出现。其他的不保证是连续过程,之间可以插入其他操作。
2.2volatile类型变量
被volatile定义之后有特性:保证变量所有线程可见,保证顺序执行。
2.3内存回顾
内存模型核心:处理原子性、可见性、顺序性。
原子性:我们可以认为基础数据类型,有原子性。可以使用 synchronized或者lock与unlock的
可见性:synchronized与final和volatile可以实现
有序性:线程内有序,线程外无序。
程序次序原则:-线程内部有序。
管程多少:unlock必须在lock之后。
volatile变量:写操作优先于读操作。
线程启动规则:start()优先于其他动作。
线程终止规则:stop()优先最弱
线程中断规则:interrupt()优先优先于中断代码检测到中断事件的发生。
对象终结规则:初始化优先于finalize-不要关心这个事情
传递性:a优先b,b优先c,那么a优先c
2.4线程的实现
->使用内核线程实现
属于系统内存线程对应一个我们的轻量线程,就我我常见线程,缺点,是有限的1:1模型。
->使用用户线程是新建
目前基本放弃,多个用户线程对应一个内核线程,而且用户线程自己维护阻塞等等 1:N模型
->使用用户线程加轻量级混合实现
许多操作系统基于此理论实现M:N线程模型
->Java线程实现
1.2之前“绿色线程”,之后也是使用系统线程
2.4线程的状态
-新建:创建为启动new
-运行:可能执行,也可以等待分配 running与ready状态
-无限期等待:没设置超时的wait,没设置超时的join,lockSupport.park()方法。
-限期等待:Thread.sleep(),设置超时的wait,设置超时的join等
-阻塞:同步区域,线程进入阻塞
-结束:以及结束stop