一、 并发编程模型分类
在并发编程中中,我们通常需要处理2个关键问题:线程之间如何通信,如何同步.
通信:是指线程怎么交换信息,线程之间通信机制有2种:共享内存,消息传递.
共享内存:线程之间通过写-读内存中的公共状态来隐式通信
消息传递:线程间没有公共状态,线程间通过明确的发送消息来显式通信.
同步:是指程序控制不同线程之间操作发生相对顺序的机制,
共享内存:程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行,是显示进行的
消息传递:消息的发送必须在消息的接收之前,因此同步是隐式进行的.
java的并发采用共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。
二、java内存模型的抽象
JMM规定:
1、 所有变量都存储在主内存(Main Memory)中。
2、 每个线程还有自己的工作内存(Working Memory),线程的工作内存中保存了该线程使用到的变量对主内存的副本拷贝,
3、 线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量仍然有工作内存的拷贝,但是由于它特殊的操作顺序性规定,所以看起来如同直接在主内存中读写访问一般)。
4、 不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。
java内存模型(JMM)控制java之间的通信,JMM主要目标是定义程序中各个变量的访问规则,决定一个线程对共享变量的写入何时对另一个线程可见,它是java线程之间通信的控制机制,保证程序是正确同步的,程序的执行具有顺序一致性.
三、java内存模型特征
Java内存模型是围绕着并发编程中原子性、可见性、有序性这三个特征来建立的,那我们依次看一下这三个特征:
1 原子性
2 可见性
JMM用volatile ,synchronized,Lock,Lock来实现可见性
3有序性
1)java提供volatile和synchronized来保证多线程之间操作的有序性,volatile关键字通过加入内存屏障来禁止指令的重排序,而synchronized关键字通过一个变量在同一时间只允许有一个线程对其进行加锁的规则来实现
2)java规定的happens-before原则,保证有序性
四、jvm内存区域
(1)线程私有
程序计数器: 记录正在执行的虚拟机字节码的地址;
虚拟机栈: 方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧;
栈帧包括: 1、 局部变量表
2、 操作栈,操作栈元素的数据类型必须与字节码指令序列严格匹配
3、 动态连接, 指向运行时常量池中该栈帧所属方法的引用,为了 动态连接使用。
4、 返回地址
正常退出,将返回值传递给调用者
异常退了,如果遇到异常,并且方法没有捕捉那么不返回值
5、 额外附加信息,由具体虚拟机实现
异常:
StackOverFlowError:当线程请求栈深度超出虚拟机栈所允许的深度时抛出
OutOfMemoryError:当Java虚拟机动态扩展到无法申请足够内存时抛出
本地方法栈: 虚拟机的Native方法执行的内存区;
异常(Exception):Java虚拟机规范规定该区域可抛出StackOverFlowError和OutOfMemoryError。
(2)线程共享区
Java堆: 对象分配内存的区域;
异常(Exception):Java虚拟机规范规定该区域可抛出OutOfMemoryError。
方法区 :存放类信息、常量、静态变量、编译器编译后的代码等数据;
常量池:存放编译器生成的各种字面量和符号引用,是方法区的一部分。
异常(Exception): Java虚拟机规范规定该区域可抛出OutOfMemoryError。