Java多线程学习笔记之三内存屏障与Java内存模型
基本内存屏障
处理器支持那种内存重排序,就会提供能够禁止相应内存重排序的的指令,这些指令就被成为基本内存屏障:StroeLoad屏障、StroeLoad屏障、LoadLoad屏障、LoadStore屏障。基本内存屏障是对一类指令的称呼(可以用XY来标识),这类指令的作用是禁止该指令左侧的X操作与该指令右侧的Y操作之间进行重排序,从而确保该指令左侧的所有X操作先于该指令右侧的Y操作被提交,即内存操作作用到主内存(或高速缓存)上。基本内存屏障只是保障其左侧的X操作先于右侧的Y操作被提交,但是它并不完全禁止重排序,XY屏障两侧的内存操作仍然可以在不越过内存屏障本身的情况下在各自范围内进行重排序,并且XY屏障左侧的非X操作和屏障右侧的非Y操作之间仍可以重排序。
基本内存屏障的具体作用
| 屏障名称 | 示例指令序列 | 具体作用 |
| StroeLoad |
Store1,Store2,Store3, StoreLoad,Load1,Load2,Load3 |
禁止StoreLoad重排序,即确保该屏障之前的任何一个写操作的结果都会在该屏障之后任何一个读操作的数据被加载之前对其他处理器来说是可同步的 |
| StoreStore |
Store1,Store2,Store3, StoreStore,Store4,Store5,Store6 |
禁止StoreStore重排序,即确保该屏障之前的任何一个写操作的结果都会在该屏障之后任何一个写操作之前对其他处理器来说是可同步的 |
| LoadLoad |
Load1,Load2,Load3, LoadLoad,Load4,Load5,Load6 |
禁止LoadLoad重排序,即确保该屏障之前的任何一个读操作的数据都会在该屏障之后的任何一个读操作之前被加载 |
| LoadStore |
Load1,Load2,Load3, LoadStore,Store1,Store2,Store3 |
禁止LoadStore重排序,确保该屏障之前的任何一个读操作的数据都会在该屏障之后的任何一个写操作的结果被冲刷到高速缓存(或主内存)之前被加载 |
- StroeLoad 屏障会清空无效化队列,并将写缓冲器中的条目冲刷到高速缓存。因此,StroeLoad 屏障既可以将其他处理器对共享变量所做的更新同步到该处理器的高速缓存中,又可以使其处理器对共享变量所做的共享对其他处理器来说是同步的。
- StoreStore屏障是通过对写缓存器中的条目进行标记来实现禁止StoreStore重排序的。StoreStore屏障会将写缓冲器中的现有条目做一个标记,以表示这些条目代表的写操作需要先于该屏障之后的写操作被提交处理器在执行写操作时如果发现写缓冲器中存在被标记的条目,那么即使这个写操作对应的高速缓存条目的状态为M或E,也不直接写入高速缓存,而是写入写缓冲器,保证StoreStore屏障之前的写操作先于之后的写操作被提交。
- LoadLoad屏障是通过清空无效化队列来实现禁止LoadLoad重排序。LoadLoad屏障会使其执行处理器根据无效化队列中的Invalidate消息删除其高速缓存中相应的副本。是处理器有机会将其他处理器对共享变量所做的更新同步到该处理器的高速缓存中,从而消除了LoadLoad重排序重排序的根源。
Java内存模型
Java内存模型定义了final、volatile、synchronized关键字的行为,并确保正确同步的Java程序能够正确的运行在不同架构的处理器上。它从“什么”的角度解答了以下几个线程安全问题。
- 原子性问题:针对实例变量、静态变量(即共享变量非局部变量)的读、写操作,哪些是具备原子性的,哪些可能不具备原子性。
- 可见性问题:一个线程对实例变量、静态变量进行的更新在什么情况下能够被其他线程所读取。
- 有序性问题:一个线程对多个实例变量、静态变量进行的更新在什么情况下在其他线程看来可以是乱序的。
在原子性方面,Java内存模型规定了对long、double型以外的基本数据类型和引用数据类型的共享变量进行读、写操作都是具有原子性的。特别的,对于volatile修饰的long、double型共享变量进行读、写操作也是具有原子型的。可见性和有序性,Java内存模型是通过happens-before这个术语解答的。
happens-before关系
假设动作A happens-before 动作B,那么Java内存模型机会保证A的操作结果对B是可见的,即A的操作结果会在B被执行请提交。happens-before关系具有传递性,如果A happens-before B,B happens-before C,则A happens-before C。Java内存模型定义了一些有关happens-before关系的规则,这些规则规定了两个动作在什么情况下具有happens-before关系,如下所示。
- 程序顺序规则:一个线程中每个动作都happens-before该线程中程序顺序上排在该动作之后的每一个动作。
- 内部锁规则:内部锁的释放happens-before后续每一个对该锁的申请。释放和申请必须是针对同一锁实例。
- volatile变量规则:对一个volatile变量的写操作happens-before后续每一个对该变量的读操作。
- 线程启动规则:调用一个线程的start方法happens-before被启动这个线程中的任何一个动作。
- 线程终止规则:一个线程中任何一个动作都happens-before该线程的join方法的执行线程在join方法返回之后所执行的任意一个动作。
Java多线程学习笔记之三内存屏障与Java内存模型的更多相关文章
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java 多线程学习笔记:生产者消费者问题
前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...
- java多线程学习笔记(七)
volatile关键字 关键字volatile的主要作用是使变量在多个线程间可见. public class PrintString { private boolean isContinue = tr ...
- java多线程学习笔记(四)
上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...
随机推荐
- 分布式理论(四)—— 一致性协议之 3PC
前言 我们说为了实现 BASE 理论,需要在可用性和一致性之间找到一个合适的一致性理论,于是,我们在上篇文章中了解了 2PC 理论,也就是两阶段提交,二阶段提交原理简单,实现方便,但是缺点则是同步阻塞 ...
- Nodejs微信公众号开发
概览 key value 项目名称 node微信公众号开发 项目描述 使用node编写接口,前后端分离获取签名数据 开发者 leinov 发布日期 2018-11-07 仓库 github地址 安装& ...
- [EWS]查找 文件夹
摘要 有时在操作exchange的时候,需要查找用户exchange文件夹,比如用户新建了一些文件夹. 一个例子 这里以查找用户outlook邮箱中的历史对话文件夹为例. private const ...
- 批量导出VBA工程中的Source
在做Excel宏相关项目的开发和维护过程中,我们经常需要导出VBA中的Source,但是Excel提供的宏编辑器中只能一个文件一个文件地导出,很不方便. 下面介绍2种批量导出的方法: 1.Source ...
- EF框架的三种模式
Database First就是先建数据库或使用已有的数据库.然后在vs中添加ADO.Net实体数据模型,设置连接并且选择需要的数据库和表.它是以数据库设计为基础的,并根据数据库自动生成实体数据模型, ...
- HDU1257(dp)
最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- JavaScript--动态加载脚本和样式(23)
一 动态脚本 // 当网站需求变大,脚本的需求也逐步变大;我们不得不引入太多的JS脚本而降低了整站的性能; // 所以就出现了动态脚本的概念,在适时的时候加载相应的脚本; 1.动态引入js文件 var ...
- Gruntfile.js文件配置项
GRUNT安装与配置 Posted on 2016-08-19 18:13 听风吹来的种子 阅读(47) 评论(0) 编辑 收藏 安装 CLI npm install -g grunt-cli//全局 ...
- css翻译名词术语
原文 本书译法 其它译法(未采用) CSS - 层叠样式表.级联样式表.样式单 cascade 层叠(机制) 级联 fallback 回退(机制.措施.方案) 后备.回落.降级 selector 选择 ...
- SSM框架下的redis缓存
基本SSM框架搭建:http://www.cnblogs.com/fuchuanzhipan1209/p/6274358.html 配置文件部分: 第一步:加入jar包 pom.xml <!-- ...