Java Memory Modle,简称 JMM,中文名称 Java内存模型,它是一个抽象的概念,用来描述或者规范访问内存变量的方式。由于各中计算机的操做系统和硬件不一样,方式机制也可能不一样,Java内存模型用于屏蔽(适配)各类差别,以此来达到访问各个平台的一致的效果。这也是Java夸平台的重要缘由之一。java
主内存: Java内存规定了全部变量都存储在主内存(Main Memory)中,各个线程又有本身的本地内存(工做内存),本地内存保存着主内存中部分变量。具体访问方式以下:面试
一、原子性(Atomicity)spring
这里的原子性如同数据库事务中是原子性,一个或多个操做要么全执行成功要么全执行失败(全不执行)。数据库
int a = 1; a++; double b = 1.5;
Java内存模型只保证单一的操做具备原子性,好比上面的 int a = 1; 是一个单子的操做,因此具备原子性。设计模式
而 a++ 操做在底层会分为三个操做:安全
1)、读取a的值给临时变量;网络
2)、临时变量a的值加1操做;数据结构
3)、将加操做后的值赋值给a。多线程
每一个操做都是原子的,但Java内存模型在多线程下并不能保证多操做具备总体原子性,由于它也不知道这个总体内有多少操做,用户想要达到多操做具备总体原子性,须要对响应的代码块作同步(synchronous)处理,好比使用 有锁的synchronized 或 无锁的CAS。框架
二、可见性(Visibility)
这里的可见性是内存可见性。
如上图,线程1和线程2在未同步的状况下对共享内存(主内存)中的变量进行访问,好比两个线程的操做都是对变量a进行加1操做。
假设线程1首先获取主内存中变量a的值,随后线程2又获取了主内存变量a的值,此时它们工做内存中a的值都是1,它们各自将a的值加1操做,而后assign至工做内存,工做内存中变量a的值都是2,而后两个线程又将值刷新到主内存,最后的结果是主内存中变量a的值是2。
虽然总体对a的值加1操做作了两次操做,但因为线程间的操做是互相隔离的,默认状况下没法感知内存变量的值在随后的变化,也就没法访问内存中最新的变量值,这就是内存可行性的问题。
如何解决内存可见性的问题?
三、有序性(Ordering)
线程内的全部操做都是有序的,既程序执行的顺序按照代码的前后顺序执行。好比下面的示例:
int a = 1; int b = 2; int c = a + b;
线程内程序会先执行 int a = 1; ,而后执行 int b = 2; 最后执行int c = a + b;。
文源网络,仅供学习之用,若有侵权请联系删除。我将面试题和答案都整理成了PDF文档,还有一套学习资料,涵盖Java虚拟机、spring框架、Java线程、数据结构、设计模式等等,但不只限于此。
关注公众号【java圈子】获取资料,还有优质文章每日送达。