所有文章也会同步更新在网站: 深夜程猿
并发编程模型的分类
在并发编程中,我们需要处理两个关键问题
- 线程之间如何通信
这里的线程是指并发执行的活动实体。通信是指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种:共享内存、消息传递。
在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信。
在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过明确的发送消息来显式进行通信。
- 线程之间如何同步
同步是指程序用于控制不同线程之间操作发生相对顺序的机制。
在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。
在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的。
Java 的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行(注意不是说同步是隐式,而是说共享内存在Java中是隐式进行),整个通信过程对程序员完全透明。如果编写多线程程序的Java程序员不理解隐式进行的线程之间通信的工作机制,很可能会遇到各种奇怪的内存可见性问题。
用一张图总结并发编程模型:
Java内存模型的抽象
在java中,所有实例域、静态域和数组元素存储在堆内存中,堆内存在线程之间共 享(本文使用“共享变量”这个术语代指实例域,静态域和数组元素)。
局部变量 (Local variables),方法定义参数(java语言规范称之为formal method parameters)和异常处理器参数(exception handler parameters)不会在线程之间共享,它们不会有内存可见性问题,也不受内存模型的影响。
Java 线程之间的通信由 Java 内存模型(本文简称为 JMM)控制,JMM 决定一个 线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:
线程之间的共享变量存储在主内存(main
memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是 JMM 的一个抽象概念,并不 真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。
Java 内存模型的抽象示意图如下: