浅谈Java内存模型、并发、多线程


Java内存模型(Java Memory Model)是围绕着在并发编程中如何处理原子性,可见性,有序性三个特性而建立的模型。
下面我简单描述一下这三个特性:
原子性:
通俗一点来说,就是要不全部做,要不全部不做。
可见性:
当A线程对某变量进行修改时,需要立即写入主存中,B线程再去主存中就能读取到最新的值,在Java中就是利用volatile来保证可见性的。
有序性:
为了提升性能,JMM是允许编译器和处理器对指令重排序的(只要结果一样,JMM就允许重排序)。因为JMM规定了as-if-serial语义,不管指令怎么重排序,程序的执行结果都不会改变,这里再谈一点,如果重排序没有遵循as-if-serial语义的话会发生什么?下面我贴图出来。

比如有这样一段代码:

int a = 0;
bool flag = false;public void write() {a = 2;              //1flag = true;        //2
}public void multiply() {if (flag) {         //3int ret = a * a;//4}
}

你以为会是1 2 3 4的执行顺序执行下来,但其实不是。

像下图一样,两个线程按照这样的顺序执行了,最后得到的结果那将不一样。这里如果展开说的话也可以聊一下多线程的synchronized和Lock。

另外,JMM具备一些先天的有序性,即不需要通过任何手段就可以保证的有序性,通常称为happens-before原则。

现在我们来聊一聊volatile关键字。
按照我自己和参照网上的意思,大概就是分成两点:

1 . 保证了不同线程对该变量操作的内存可见性
2 . 禁止指令重排序

这里又谈到了内存可见性和重排序,记住几点,只要被volatile关键字修饰的共享变量,每次针对该变量的操作都激发一次load and save,这样才保证了内存的可见性。

如图所示,线程会先从主存中读变量的值,然后加载到工作内存中,处理器处理后再传到工作内存副本中,再写进主存中去,这就涉及到原子性,要不全部做完,要不全部不做。

假设A线程从主存中拿出一个变量值为0做了+1,修改完只写到了工作内存中,然后B线程又拿了该变量出来做了+1操作,现在A线程将该变量存到主存中,B线程也将该变量存进主存中,你说这个时候变量值是几?
所以JMM就是围绕着在并发编程中如何处理原子性,可见性,有序性三个特性而建立的模型,通过解决这三个问题,可以解决缓存不一致的问题。而volatile跟可见性和有序性都有关。

请注意!这里我可没说volatile 一定保证了原子性。在某些情况下是可以保证原子性,某些情况下又不可以,如果是复合操作的话(例如volatile++),则不能保证它的原子性。例如:

public volatile int num = 0;

如果num做自增,假设A线程进来,自增到了5,这个时候发生了阻塞,没有自增,所以也没有触发volatile规则,这个时候如果B线程再进来拿到num,再做了自增,变成了6再写到主存中。A线程恢复继续从工作内存中拿5开始自增,得到了6再写到主存中去。想想是不是哪里不对劲?是的,两个线程对num都进行了自增,但是只得到了一次的结果。这就不是我们想要的结果了!这时候就需要给线程们加上线程锁或者其他等等。

并发编程与多线程是我们开发中常遇见的问题,因为是第一次写,也参照了很多前辈的博客,多担待。有错请务必指出,转载请注明出处谢谢。

浅谈Java内存模型、并发、多线程相关推荐

  1. java内存模型浅析_浅谈java内存模型

    不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结jav ...

  2. java方法区对象类型_浅谈Java内存区域与对象创建过程

    一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...

  3. 深入理解JVM虚拟机(十):Java内存模型与多线程

    1. 硬件的效率与缓存一致性 由于存储设备和处理器运算速度之间的存在巨大的差异,现在计算机系统在内存与处理器之间加入高速缓存来作为处理器与内存之间的缓冲.将处理器需要的数据复制到缓存中,让处理器可以快 ...

  4. 再谈java内存模型

    不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的.其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改.总结jav ...

  5. 【精心总结】java内存模型和多线程必会知识

    内存模型 (1)java内存模型到底是个啥子东西? java内存模型是java虚拟机规范定义的一种特定模型,用以屏蔽不同硬件和操作系统的内存访问差异,让java在不同平台中能达到一致的内存访问效果,是 ...

  6. 重点知识学习(8.2)--[JMM(Java内存模型),并发编程的可见性\原子性\有序性,volatile 关键字,保持原子性,CAS思想]

    文章目录 1.JMM(Java Memory Model) 2.并发编程的可见性 3.并发编程的有序性 4.并发编程的原子性 5.volatile 关键字 6.保持原子性: 加锁,JUC原子类 加锁 ...

  7. 浅谈java内存分析和垃圾收集器

    目录: 1.内存分析 2.两种垃圾回收机制和原理 3.对垃圾回收机制的简单理解 1.内存分析: (1)栈区: (1)(方法执行的内存模型)也就是说每一个方法执行相关调用都在栈里边,每个方法被调用都会创 ...

  8. java 内存分配参数_浅谈JAVA内存分配与参数传递

    java中方法的参数传递方式只有一种:值传递. java内存分配: 1.栈:存放 基本类型的数据.对象的引用(类似于c语言中的指针) 2.堆:存放用new产生的数据 3.静态域:存放在对象中用stat ...

  9. 浅谈java内存分配和回收策略

    一.导论 java技术体系中所提到的内存自动化管理归根结底就是内存的分配与回收两个问题,之前已经和大家谈过java回收的相关知识,今天来和大家聊聊java对象的在内存中的分配.通俗的讲,对象的内存分配 ...

最新文章

  1. 新瓶旧酒ASP.NET AJAX(6) - 客户端脚本编程
  2. [SCOI2014]方伯伯的OJ
  3. 大气新闻出版社网站模板
  4. win10 SQL SERVER 2017安装详解
  5. 2021年中国单索运动滑轮市场趋势报告、技术动态创新及2027年市场预测
  6. c语言编程中如何对其,C语言内存对齐详解(3)
  7. Win7平台下配置Sublime Text2 的C++编译环境
  8. 《Java并发编程的艺术》笔记
  9. springboot读取properties(yml)的几种常用方式
  10. 基于JavaWeb的网上鞋店商城的设计实现
  11. 八爪鱼批量爬取html中的数据,批量采集网页数据 - 八爪鱼采集器
  12. Android熟悉使用PackageManager,ActivityManager,MemoryInfo,引入布局文件Include的使用,values的管理
  13. 一个数据分析师的职业规划:人生本来就应该提前做好准备
  14. 免费的聊天机器人API
  15. 梦幻星空html,HTML5特效展示,梦幻星空
  16. 批量修正字幕乱码(powershell)
  17. 2021年河南省高考成绩位次查询,2021年河南高考位次查询及一分一段表排名查询...
  18. 《R语言与数据挖掘》⑤高级绘图工具【lattice包】【ggplot2】【交互式】
  19. javascript面向对象(一):object基础以及构造函数详解
  20. Excel的统计函数(1)

热门文章

  1. Win10离线安装.net framework 3.5(错误:0x8024402c DISM失败解决方案)
  2. windows update更新返回错误码统计(WUSA.exe)
  3. 论文笔记 | 谷歌 Soft Prompt Learning ,Prefix-Tuning的 -> soft promt -> p tuning v2
  4. mysql-Explain关键字
  5. 自己颁发SSL证书,浏览器不识别解决方法
  6. 开发和实现一个疫情隔离区的订餐系统
  7. java biginteger 取模_Java BigInteger类
  8. CF1369D TediousLee 翻译
  9. 个人作业 - 2017软件工程实践总结
  10. clinux 防火墙增加白名单_linux防火墙白名单设置方法