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 ...
随机推荐
- 关于 checkbox 的一些操作
获取checkbox选中的状态 $("#checkbox").is(":checked"); 设置 checkbox 的状态 $("#checkbox ...
- 在HTML中实现两个div并排显示
在HTML中让两个div并排显示,通常情况下有三种实现方式,包括: (1)设置为行内样式,display:inline-block (2)设置float浮动 (3)设置position定位属性为abs ...
- 【JavaWeb】Spring相关错误记录
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: ...
- cf 908B
B - New Year and Buggy Bot 思路:刚开始看到这个题的时候,一头雾水,也不知道要干什么,后来百度翻译了了一遍,看明白了,不得不说自己的英语太差了,好了,步入正题: 给你n行m列 ...
- CSS——textarea多行文本框禁止拖动问题解决
文本框这样配置就好 textarea{ resize:none; }
- Fiddler过滤VsHub请求
Fiddler过滤掉VS2015 VsHub请求 打开VS2015, Tools --> Options --> Debugging --> General --> unche ...
- 02-15Android学习进度报告十五
今天学习了关于ListView Item多布局的实现.感觉有点困难. 何为ListView Item多布局,打个比方,QQ这种聊天列表 代码示例如下: public class MutiLayoutA ...
- 5G时代开启,这些新兴职业决定你的后半生
近段时间,高考志愿填报成为牵动千万家庭的头等大事.事实上,除了学校间的差距外,专业的优劣也在很大程度上决定着人们未来职场生涯的潜力.血淋淋的事实告诉我们,只有选对专业,才能让自己的人生实现升华,并避免 ...
- js 子窗口调用父框框方法
父窗口 子窗口
- linux环境安装包方式
概述 安装有很多种,有时我们会混淆视听不知在什么场景或什么情况下用什么命令,下面讲解下几种安装命令的使用.希望对大家有帮助~ 详解 pip install kuming或 python -m pip ...