并发编程之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和缓存一 ...
随机推荐
- Spring Boot:使用Redis存储技术
综合概述 Redis是一个开源免费的高性能key-value数据库,读取速度达110000次/s,写入速度达81000次/s.Redis支持丰富的数据类型,如Lists, Hashes, Sets 及 ...
- 移动IM开发指南1:如何进行技术选型
<移动IM开发指南>系列文章将会介绍一个IM APP的方方面面,包括技术选型.登陆优化等.此外,本文作者会结合他在网易云信多年iOS IM SDK开发的经验,深度分析实际开发中的各种常见问 ...
- C++标准库(体系结构与内核分析)(侯捷第一讲)
一.C++标准库介绍 C++标准库:C++ Standard Library C++标准库与STL有什么关系: STL:Standard Template Library STL包含6大部件,基本占标 ...
- 系统学习 Java IO (四)----文件的读写和随机访问 FileInputStream/FileOutputStream & RandomAccessFile
目录:系统学习 Java IO---- 目录,概览 文件输入流 FileInputStream 这是一个简单的FileInputStream示例: InputStream input = new Fi ...
- excel for mac打开csv文件不分列
参考链接:http://www.1207.me/archives/247.html excel for mac在打开csv文件(逗号分隔的文本文件)的时候,不能像windows那样分列,而且全都挤在一 ...
- docker容器中使用pip有警告
docker容器中使用pip有警告 /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:334: ...
- Presto 0.22.0 安装记录
1. 下载 & 解压 # 下载 wget https://repo1.maven.org/maven2/com/facebook/presto/presto-server/0.220/pres ...
- JS高级程序设计第2章--精简版
前言:这次是二刷了,想暑假做一次完整的笔记,但用本子来写笔记的话太贵了,可能哪天还丢了..所以还是博客好== 第二章:在HTML中使用JavaScript 2.1 <script>元素: ...
- BZOJ 1026:windy数(数位DP)
http://www.lydsy.com/JudgeOnline/problem.php?id=1026 1026: [SCOI2009]windy数 Time Limit: 1 Sec Memor ...
- 【带着canvas去流浪(11)】Three.js入门学习笔记
目录 一. 资料推荐及建议 二. Three.js中的基本概念 三.重点笔记 四.补充示例 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址: ...