在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么。然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性。

为什么要有内存模型

  在计算机中,所有的运算操作都是由CPU的寄存器来完成的,CPU指令的执行需要涉及到数据的读写操作,而CPU只能访问主存中的数据。随着技术的发展,CPU的执行速度越来越快,而内存的访问速度没有太大的变化,导致CU每次操作主存都要等待很长的时间。于是就有了在CPU与主存之间添加缓存的设计。

内存模型:CPU Cache模型

  目前缓存的数量达到了3级,最接近CPU的缓存称为L1,然后为L2、L3和主存。由于程序指令和数据的行为和热点分布差异比较大,因此将L1又细分为L1i(istruction)、L1d(data)。

CPU的出现是为了解决CPU直接访问主存效率低下的问题。程序在运行过程中,会将运算所需的数据从主存中复制一份到Cache中,这样CPU在计算时就可以直接对CPU Cache中的数据进行读写,当运算结束后,再将Cahce中的最新数据刷新到主存中。
虽然缓存的出现极大地提升了CPU的吞吐能力,但是也导致了缓存不一致的问题。这是因为CPU都是对Cache中的数据进行读写,不同线程之间的工作内存是相互独立的,对某个线程工作空间中的数据进行更新,可能会无法及时同步到其它缓存中。
为了保证数据的正确性,内存模型定义了共享内存系统中多线程程序读写操作行为的规范。

Java内存模型

Java内存模型(Java Memory Model ),简称JMM,是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能得到一致效果的机制及规范。其目的是解决多线程通过主内存进行通信时,存在的原子性、可见性(缓存一致性)以及有序性问题。(关于原子性、可见性(缓存一致性)以及有序性,我们将会在”并发编程的三大特性“中详细讲解)
JMM决定了一个线程对共享变量的写入何时对其它线程可见,定义了线程与主存之间的关系:
  • 共享变量存储于主存中,每个线程都可以访问
  • 每个线程都有私有的工作内存,也称为本地内存
  • 工作内存中只存储共享变量的副本
  • 线程不能直接操作主存,只有操作了本地内存后才能写入主存
  • 每一个线程都不能访问其他线程的本地内存

 并发编程的三大特性

并发编程有三大特性:原子性、可见性、有序性。
  • 原子性:是指在一次操作或多次操作中,要么所有的操作都得到执行,要么都不执行。【类似于事务】
    • JMM只保证了基本读取和赋值的原子性操作
    • 多个原子性操作的组合不再是原子性操作
    • 可以使用synchronized/lock保证某些代码片段的原子性
    • 对于int等类型的自增操作,可以通过java.util.concurrent.atomic.*保证原子性
  • 可见性:是指一个线程对共享变量进行了修改,其他线程可以立即看到修改后的值。
  • 有序性:是指代码在执行过程中的先后顺序是有序的。【Java编译器会对代码进行优化,执行顺序可能与开发者编写的顺序不同(指令重排)】
并发编程时,保证三大特性的方式有三种:
    • 使用volatile关键字修饰变量
      • 当一个变量被volatile关键字修饰时,对于共享变量的读操作会直接在主存中进行,对于共享变量的写操作是先修改本地内存,修改结束后直接刷到主存中。(未被volatile修饰的变量被修改后,什么时候最新值会被刷到主存中是不确定的)
    • 使用synchronized关键字修饰方法或代码块
      • synchronized关键字能保证同一时刻只有一个线程获得锁然后执行同步方法,并且确保锁释放之前,会将修改的变量刷入主存。
    • 使用JUC提供的显式锁Lock
      • Lock能保证同一时刻只有一个线程获得锁然后执行同步方法,并且确保锁释放之前,会将修改的变量刷入主存。

 补充

  Java中提供了一系列和并发处理相关的关键字,比如volatile、synchronized等,其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字。

参考文献

  • 汪文君《Java高并发编程详解-多线程与架构设计》

转载于:https://www.cnblogs.com/BlueStarWei/p/11278621.html

并发编程之Java内存模型相关推荐

  1. 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则

    前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...

  2. python电路模型编程_14、python开发之路-并发编程之I/O模型

    十四.并发编程之I/O模型 http://www.cnblogs.com/linhaifeng/articles/7454717.html 1.模型介绍 1.1 IO种类 (1)* blocking ...

  3. Java并发编程:Java内存模型JMM

    简介 Java内存模型英文叫做(Java Memory Model),简称为JMM.Java虚拟机规范试图定义一种Java内存模型来屏蔽掉各种硬件和系统的内存访问差异,实现平台无关性. CPU和缓存一 ...

  4. 多线程之Java内存模型(JMM)(一)

    在未正确使用锁的时候,多线程的程序可能变的很容易出错,并且难以排查.而JMM则给我们一种规范,它描述了多线程程序如何与内存交互. 与文无关 JMM大致描述: JMM描述了线程如何与内存进行交互.Jav ...

  5. java 内存模型 多线程_Java 高并发三:Java内存模型和线程安全详解

    网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存.数据在主存中会有一份,在工作内存中也有一份.工作内存和主存之间会有各种原子操作去进行同步. 下图来源于这 ...

  6. 【并发编程】JAVA内存模型

    JAVA内存模型即JMM(Java Memory Model),有些人会和Java内存结构混淆.虽然两者名字很接近,但描述的为不同内容.Java内存结构描述的是JVM对内存的逻辑划分,我们在学习垃圾回 ...

  7. JUC并发编程之Java线程(二)

    二.Java线程 2.1 创建和运行线程 方法一:Thread创建线程方式: 继承Thread类 匿名内部类方式 public class CreateThread01 {public static ...

  8. Java并发编程之Java线程池

    Java线程池: 线程池的核心配置参数: //线程等待任务的超时时间,当线程池的线程个数超过corePoolSize时生效,当线程等待任务的时间超过keepAliveTime时,线程池会停止超过cor ...

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

    浅谈Java内存模型.并发.多线程 Java内存模型(Java Memory Model)是围绕着在并发编程中如何处理原子性,可见性,有序性三个特性而建立的模型. 下面我简单描述一下这三个特性: 原子 ...

最新文章

  1. DARPA:我们需要一种新型的芯片技术来确保人工智能的长足发展
  2. 一个登录框实现不同的登录验证
  3. Vitamio FAQ(2012-11-20 )
  4. ElasticSearch---------------------Elasticsearch Clients---------------------JAVA API
  5. 常用json框架介绍和Jackson返回结果处理
  6. 收藏 : 50个Excel逆天功能,一秒变“表哥”
  7. Qt图形界面编程入门(5)
  8. Termux配置ssh连接
  9. 策略模式 是一种好策略 -07
  10. android 打开免打扰模式,Android 6.0设置模块免打扰功能浅析
  11. 用CSS绘制实体三角形并说明原理
  12. pjsip代码分析(1)——modules框架
  13. nxlog收集linux日志,Nxlog——日志采集神器简介
  14. 要做好云计算所需要的成本,主要分为哪六大成本?
  15. java listener 模式_Java和GUI-根据MVC模式,ActionListener属于哪里?
  16. oracle重做日志教程,Oracle重做日志管理
  17. linux下如何用gcc编译器生成lst文件?
  18. html表单验证邮箱表达式,Javascript正则表达式实现表单验证
  19. 调用百度aip实现短语音翻译(附代码)
  20. 计算机的USB接口可以扩展吗,电脑的USB接口不够用怎么办?别急,我来支招!

热门文章

  1. python【力扣LeetCode算法题库】面试题 08.11- 硬币
  2. java xml 变量替换_Java JAXB如何将XmlElements重新定义为现有变量
  3. python 自定义词典_pyhanlp用户自定义词典添加
  4. genrsa out php,PHP进行RSA加密解密
  5. 算法与数据结构(2)
  6. 天猫php采集列表,QueryList: QueryList是一个基于phpQuery的通用列表采集类,是一个简单、 灵活、强大的采集工具,采集任何复杂的页面 基本上就一句话就能搞定了。...
  7. 湖南网络推广浅析外链怎么发才会更快的收录?
  8. 网站优化之关键词优化
  9. EventBus初解
  10. 机器翻译引擎的基本原理 ——LSTM