Java并发编程:Java内存模型JMM
简介
Java内存模型英文叫做(Java Memory Model),简称为JMM。Java虚拟机规范试图定义一种Java内存模型来屏蔽掉各种硬件和系统的内存访问差异,实现平台无关性。
CPU和缓存一致性
讲JMM之前,我们应该先了解下CPU和缓存一致性的问题。计算机在执行程序的时候,每条指令都是在CPU中执行的,而执行的时候,又要和数据打交道。而计算机上面的数据,是存放在内存当中的。随着CPU的高速发展,从内存中读取和写入数据的过程和CPU的执行速度比起来差距就会越来越大,这导致了CPU不能满负荷的工作,需要去等待数据从内存中读取或者写入。
为了解决内存和CPU速度不一致的问题,继而引入了高速缓存这么一个东西。在CPU和内存之间,放一个高速缓存作为缓冲,这样一来就提升了CPU的读写速度。
高速缓存解决了处理器和内存速度的矛盾,但是却引入了另外一个复杂的问题——缓存一致性。在多处理器系统中,每个处理器都有自己的高速缓存,而内存又是各处理器共享的,这就可能导致各自的缓存数据不一致的情况。
为了解决缓存一致性的问题,各个处理器访问缓存时都遵循一定的协议,在读写时根据协议来操作,进而保证缓存的一致性。为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。
Java内存模型(JMM)
Java虚拟机规范试图定义一种Java内存模型来屏蔽掉各种硬件和系统的内存访问差异,实现平台无关性。其底层是根据不同系统的缓存读写协议分别进行处理的。开发者不用去关心各系统的差异,因为JVM已经帮我们屏蔽了各系统的细节差异,我们只需要关注JMM即可。
Java内存模型就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。
Java内存模型定义了线程和主内存之间的抽象关系,Java各线程之间的通信是有Java内存模型所控制的。从抽象来讲,线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的工作内存(本地内存)(local memory),本地内存中存储了该线程以读 / 写共享变量的副本。
Java内存模型里所说的主内存,和工作内存(本地内存),都是抽象的概念,真实是不存在的,要区别于CPU高速缓存和内存设备。JMM只是JVM为了屏蔽系统内存操作的差异所抽象出来的概念。
主内存和工作内存(本地内存)
Java内存模型规定了所有的变量都在主内存中,每条线程都有自己的工作内存。Java线程工作的时候,从主内存load数据到自己的工作内存中,这时工作内存就持有了主内存的一份数据拷贝。线程操作完之后,把数据重新save回主内存中。
线程安全问题
理解Java内存模型,是理解线程安全问题的基础。知道JMM有主内存和工作内存之分之后,我们就很容易的理解多个线程操作同个共享变量可能引发的数据不一致的问题。假设有如下代码:
public class Main {
private static int a = 0;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
a = a+1;
}).start();
}
Thread.sleep(3000);
System.out.println(a);
}
}
这里有一万个线程去操作共享数据a,如果不存在并发问题的话,“预期的结果应该是10000”。执行程序,结果:
结果一:
结果二:
结果三:
实际的结果是没法预测的,理解了上面主内存和工作内存之分之后,相信你很快能理解其中的原因。假设a等于0,同时存在两个线程对其做了++操作,这时两个工作内存的a都是1,回写到主内存的时候也是1,“相当于少了一个1了”。
总结
本文介绍了Java的内存模型,这里需要强调的一点是,Java内存模型不同于Java内存结构,不要将二者概念混淆。Java内存模型是为了解决各线程之间的通信所抽象出来的概念,Java内存结构则是Java中的数据存储形式,也就是经常提到的堆内存、栈内存等。
Java并发编程:Java内存模型JMM的更多相关文章
- Java并发编程、内存模型与Volatile
http://www.importnew.com/24082.html volatile关键字 http://www.importnew.com/16142.html ConcurrentHash ...
- Java并发编程-Java内存模型
JVM内存结构与Java内存模型经常会混淆在一起,本文将对Java内存模型进行详细说明,并解释Java内存模型在线程通信方面起到的作用. 我们常说的JVM内存模式指的是JVM的内存分区:而Java内存 ...
- 高并发第二弹:并发概念及内存模型(JMM)
高并发第二弹:并发概念及内存模型(JMM) 感谢 : 深入Java内存模型 http://www.importnew.com/10589.html, cpu缓存一致性 https://www.cnbl ...
- x86-TSO : 适用于x86体系架构并发编程的内存模型
Abstract : 如今大数据,云计算,分布式系统等对算力要求高的方向如火如荼.提升计算机算力的一个低成本方法是增加CPU核心,而不是提高单个硬件工作效率. 这就要求软件开发者们能准确,熟悉地运用高 ...
- 【并发编程】- 内存模型(针对JSR-133内存模型)篇
并发编程模型 1.两个关键问题 1)线程之间如何通信 共享内存 程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信 消息传递 程之间没有公共状态,线程之间必须通过发送消息来显式进行通信 ...
- Java并发编程:Java Thread 的 sleep() 和 wait() 的区别
1. start 和 run 方法解释: 1) start: 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码.通过调用Thread类 ...
- Java并发编程:Java Thread 的 run() 与 start() 的区别
1. sleep 和 wait 方法解释 sleep()方法是Thread类里面的,主要的意义就是让当前线程停止执行,让出cpu给其他的线程,但是不会释放对象锁资源以及监控的状态,当指定的时间到了之后 ...
- Java并发编程:Java Thread方法join的简单总结
虽然关于讨论线程join方法的博客已经很多了,不过个人感觉挺多都讨论得不够全面,所以我觉得有必要对其进行一个全面的总结. 一.作用 Thread类中的join方法的主要作用就是同步,它可以使得线程之间 ...
- 《Java并发编程的艺术》笔记
第1章 并发编程的挑战 1.1 上下文切换 CPU通过时间片分配算法来循环执行任务,任务从保存到再加载的过程就是一次上下文切换. 减少上下文切换的方法有4种:无锁并发编程.CAS算法.使用最少线程.使 ...
- java并发编程资料
并发这玩意很有用,把自己在网上看过觉得总结的很好的资料分享出来.猛击下面的地址查看吧 java并发编程:线程池的使用说明 java并发编程系列文章 Java并发性和多线程专题 并发工具类 Java 7 ...
随机推荐
- 【C语言】(数组方式)求n名同学的平均成绩
原理就不说了 代码: #include <stdio.h> int main() { ], sum = ; int i; printf("请输入5名童鞋的成绩:\n") ...
- java 对图片的添加文字描述,以及两张图片合成一张
最近公司一个需要,需要把商品的优惠卷分享链接,生成一个二维码然后和商品主图合成一张,并且在新合成的主图增加商品信息的描述,好了直接看合成后图片的样式 下面我就直接贴代码,首先是Contorller层 ...
- js分享微信 ,微博 ,qq空间
目前pc微信分享,是通过扫描二维码进行分享 var _title,_source,_sourceUrl,_pic,_showcount,_desc,_summary,_site, _width = , ...
- 计算机二级-C语言-字符数字转化为整型数字。形参与实参类型相一致。double类型的使用。
//函数fun功能:将a和b所指的两个字符串分别转化成面值相同的整数,并进行相加作为函数值返回,规定只含有9个以下数字字符. //重难点:字符数字转化为整型数字. #include <stdio ...
- Java的反射机制之反向抽烟
show me the code and take to me,做的出来更要说的明白 GitHub项目JavaHouse同步收录 喜欢就点个赞呗! 你的支持是我分享的动力! 引入 反射是一种不按套路处 ...
- window下jenkins+allure+邮箱发送
一.安装allure 1)下载 allure.zip 下载地址:allure-github: https://github.com/allure-framework/allure2 2)解压到本地目录 ...
- POJ3662 Telephone Lines (dijkstra+二分)
Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncoop ...
- Spring AOP 中 advice 的四种类型 before after throwing advice around
spring AOP(Aspect-oriented programming) 是用于切面编程,简单的来说:AOP相当于一个拦截器,去拦截一些处理,例如:当一个方法执行的时候,Spring 能够拦截 ...
- 一、FreeMarker实现对js和css压缩
1.代码压缩理解:实际上就是将原有的文本中无用的注释.空行.空格去掉来压缩文件的大小.进行js和css压缩会带来如下好处:1)减小了文件的体积,减少文件占用的内存;2)减小了网络传输量和带宽占用; 3 ...
- Session服务器之Session复制!
全部运行在Tomcat下 第一台主机:192.168.200.131 安装nginx 修改hosts文件 [root@localhost ~]# vim /etc/hosts 192.168.200 ...