通过本篇文章,你可以从概念上理解java对于编发编程遇到的问题解决的原则或者是思想(JMM).
引言
从聊聊java并发编程 [核心问题以及java解决方案],聊聊java并发编程 [java实现的基石] 这两篇文章,我们聊到了并发编程的核心问题,以及java依赖相关工具
实现。本篇文章,我们开始深入浅出聊下这些工具。
部分概念
- 线程之间的同步
- 同步具体是指
程序中不同线程间操作发生的相对顺序
。 - java 共享内存模型表示程序员必须显示的对某个方法或代码块互斥执行。是显式的。
- 同步具体是指
- 线程之间的通信
- 通信具体是指
线程之间交换信息
。 - java共享内存模型 表示: 线程间的通信都是隐式通讯的。
- 通信具体是指
- JVM 部分概念
- 具体可以看这篇文章
现存的问题
- 由于JVM多线程对共享内存区域是有线程不安全的。
- 所以JVM定义了一组规则(JMM) 来解决这个问题(本质上是内存可见性)。
- JMM 解决这个问题的有下面几个原则:
- 原子性
- 有序性
- 可见性(主)
JMM相关概念以及理解
- JMM(Java Memory Model)即 java 内存模型。是一个抽象的概念规范。其约定了程序中的各个变量(包括实例,静态字段以及其他对象数组元素)的访问方式。
- JMM 主要有主内存,工作内存两个概念,来解决线程间的通信和同步问题。
- 主要解决内存可见性
JMM 主内存
- 线程之间的共享变量(所有实例域,静态域,数组元素,这些都是存储在JVM堆内存中)存储在主内存中。
- 主要存储Java实例对象。无论该对象是局部变量还是成员变量,自然也包括,共享的类信息,,静态变量。基本可以理解所有的数据都会在主内存中存在。 多个线程同时操作某个变量,就会引发线程不安全。
- 实际存储:
- 每个线程都有自己的私有的本地内存。本地内存存储了该线程的读/写共享变量的副本。
- 从JVM角度来讲:JMM内存因为是私有的数据变量,某种程度上可以理解为JVM线程栈(虚拟机栈,本地方法栈,程序计数器)
JMM 抽象示意图
- JMM的抽象示意图 (来源于<Java并发编程的艺术>)
- 举例(例子来源于<Java并发编程的艺术>)
- 除了JVM自身提供的对基本数据类型读写操作的原子性外,对于方法级别或者代码块级别的原子性操作,可以使用synchronized关键字或者锁保证程序执行的原子性。
JMM 解决可见性
- 使用sychronized 以及volatile 都可以在一个线程对某个变量修改后,其他变量可见。
JMM 解决有序性
- 有序性涉及到了指令重排(可以简单理解为硬件系统会将程序的指令做一次优化, 优化的时候可能会存在结果不一致的存在)。
- 这种使用volatile就可以解决。 volatile是禁止重排序优化。
参考大佬(膜拜)
- 《java并发编程的艺术》方腾飞 魏鹏 程晓明 著
- 全面理解Java内存模型(JMM)及volatile关键字
- 深入理解Volatile