并发编程之Java内存模型
在介绍Java内存模型之前,先来了解一下为什么要有内存模型,以及内存模型是什么。然后我们基于对内存模型的了解,学习Java内存模型以及并发编程的三大特性。
为什么要有内存模型
在计算机中,所有的运算操作都是由CPU的寄存器来完成的,CPU指令的执行需要涉及到数据的读写操作,而CPU只能访问主存中的数据。随着技术的发展,CPU的执行速度越来越快,而内存的访问速度没有太大的变化,导致CU每次操作主存都要等待很长的时间。于是就有了在CPU与主存之间添加缓存的设计。
内存模型:CPU Cache模型
目前缓存的数量达到了3级,最接近CPU的缓存称为L1,然后为L2、L3和主存。由于程序指令和数据的行为和热点分布差异比较大,因此将L1又细分为L1i(istruction)、L1d(data)。
Java内存模型

- 共享变量存储于主存中,每个线程都可以访问
- 每个线程都有私有的工作内存,也称为本地内存
- 工作内存中只存储共享变量的副本
- 线程不能直接操作主存,只有操作了本地内存后才能写入主存
- 每一个线程都不能访问其他线程的本地内存
并发编程的三大特性
- 原子性:是指在一次操作或多次操作中,要么所有的操作都得到执行,要么都不执行。【类似于事务】
- JMM只保证了基本读取和赋值的原子性操作
- 多个原子性操作的组合不再是原子性操作
- 可以使用synchronized/lock保证某些代码片段的原子性
- 对于int等类型的自增操作,可以通过java.util.concurrent.atomic.*保证原子性
- 可见性:是指一个线程对共享变量进行了修改,其他线程可以立即看到修改后的值。
- 有序性:是指代码在执行过程中的先后顺序是有序的。【Java编译器会对代码进行优化,执行顺序可能与开发者编写的顺序不同(指令重排)】
- 使用volatile关键字修饰变量
- 当一个变量被volatile关键字修饰时,对于共享变量的读操作会直接在主存中进行,对于共享变量的写操作是先修改本地内存,修改结束后直接刷到主存中。(未被volatile修饰的变量被修改后,什么时候最新值会被刷到主存中是不确定的)
- 使用synchronized关键字修饰方法或代码块
- synchronized关键字能保证同一时刻只有一个线程获得锁然后执行同步方法,并且确保锁释放之前,会将修改的变量刷入主存。
- 使用JUC提供的显式锁Lock
- Lock能保证同一时刻只有一个线程获得锁然后执行同步方法,并且确保锁释放之前,会将修改的变量刷入主存。
补充
Java中提供了一系列和并发处理相关的关键字,比如volatile、synchronized等,其实这些就是Java内存模型封装了底层的实现后提供给程序员使用的一些关键字。
参考文献
- 汪文君《Java高并发编程详解-多线程与架构设计》
并发编程之Java内存模型的更多相关文章
- 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则
前言 楼主这个标题其实有一种作死的味道,为什么呢,这三个东西其实可以分开为三篇文章来写,但是,楼主认为这三个东西又都是高度相关的,应当在一个知识点中.在一次学习中去理解这些东西.才能更好的理解 Jav ...
- 并发编程之java内存模型(Java Memory Model ,JMM)
一.图例 0.两个概念 Heap(堆):运行时的数据区,由垃圾回收负责,运行时分配内存(所以慢),对象存放在堆上 如果两个线程,同时调用同一个变量,怎两个线程都拥有,该对象的私有拷贝 (可以看一下,T ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- Java并发编程(1)-Java内存模型
本文主要是学习Java内存模型的笔记以及加上自己的一些案例分享,如有错误之处请指出. 一 Java内存模型的基础 1.并发编程模型的两个问题 在并发编程中,需要了解并会处理这两个关键问题: 1.1.线 ...
- 并发研究之Java内存模型(Java Memory Model)
Java内存模型JMM java内存模型定义 上一遍文章我们讲到了CPU缓存一致性以及内存屏障问题.那么Java作为一个跨平台的语言,它的实现要面对不同的底层硬件系统,设计一个中间层模型来屏蔽底层的硬 ...
- 高并发和多线程——Java内存模型
个人理解: 1.并发编程分为三个核心:分工.同步.互斥 2.CPU.内存.I/O存在速度差异问题. 3.线程切换导致原子性问题.编译优化导致有序性问题.缓存导致可见性问题. 4.Java内存模型规范了 ...
- 【Java并发系列】--Java内存模型
Java内存模型 1 基本概念 程序:代码,完成某一个任务的代码序列(静态概念) 进程:程序在某些数据上的一次运行(动态) 线程:一个进程有一个或多个线程组成(占有资源的独立单元) 2 JVM与线程 ...
- 【Java并发基础】Java内存模型解决有序性和可见性
前言 解决并发编程中的可见性和有序性问题最直接的方法就是禁用CPU缓存和编译器的优化.但是,禁用这两者又会影响程序性能.于是我们要做的是按需禁用CPU缓存和编译器的优化. 如何按需禁用CPU缓存和编译 ...
- Java并发编程:Java内存模型JMM
简介 Java内存模型英文叫做(Java Memory Model),简称为JMM.Java虚拟机规范试图定义一种Java内存模型来屏蔽掉各种硬件和系统的内存访问差异,实现平台无关性. CPU和缓存一 ...
随机推荐
- 分享Sql Server 2008 r2 数据备份,同步服务器数据(二.本地发布,订阅)
上一篇文章中写到了数据库的本地备份,这一篇主要分享一下关于不同服务器的数据备份,主要是使用sql server中的本地发布,本地订阅功能,在数据库的读写分离中,也会经常性的用到这个功能. 复制-> ...
- centos 5.5版本中添加ext4格式
1.我在使用centos 5.5版本做练习的时候发现默认是不支持ext4文件格式. 在添加硬盘后,用fdisk -l 查看到信息如下: 分区完后,使用命令:mkfs -t ext4 /dev/sdb会 ...
- Spark学习之路(九)—— Spark SQL 之 Structured API
一.创建DataFrame和Dataset 1.1 创建DataFrame Spark中所有功能的入口点是SparkSession,可以使用SparkSession.builder()创建.创建后应用 ...
- C盘内存杀手:IDEA缓存文件!
软件虽然装在D盘,C盘仍然还有一个文件夹 里面有两个文件夹: config 目录是 IntelliJ IDEA 个性化化配置目录,或者说是整个 IDE 设置目录.也是我个人认为最重要的目录,没有之一, ...
- ASP.NET Core MVC 之路由(Routing)
ASP.NET Core MVC 路由是建立在ASP.NET Core 路由的,一项强大的URL映射组件,它可以构建具有理解和搜索网址的应用程序.这使得我们可以自定义应用程序的URL命名形式,使得它 ...
- java中方法的重载和覆盖
java中方法的重载和覆盖 先来了解一下这两个名词的含义. 重载: 在一个类当中才可以重载,方法名相同,参数个数不同或参数个数相同而参数类型不同. 覆盖: 又称重写,在派生类(子类)中重写基类(父类) ...
- 详解Linux运维工程师必备技能
张戈大神是腾讯的一名运维,张戈博客也是我接触到第一个 Linux 运维师的博客,最近也在接触 Linux,说到工具,在行外可以说是技能,在行内一般称为工具,就是运维必须要掌握的工具. 我就大概列出这几 ...
- python函数之 range()
Python range() 函数用法 python range() 函数可创建一个整数列表,一般用在 for 循环中. 函数语法 range(start, stop[, step]) 参数说明: ...
- (持续更新)Qt3D 学习资源
目录 一.前言 1.1 什么是Qt3D 1.2 Qt3D 的利与弊 利:原生支持 弊处:资料过少 二.学习建议 2.1 OpenGL 学习资料 2.2 Qt3D 资料 2.2.1 视频资料 2.2.4 ...
- vboxnetctl: no such file or directory
 sudo /Library/StartupItems/VirtualBox/VirtualBox restart sudo /Library/StartupItems/VirtualBox/Vir ...