基本内存屏障

  处理器支持那种内存重排序,就会提供能够禁止相应内存重排序的的指令,这些指令就被成为基本内存屏障: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内存模型的更多相关文章

  1. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  2. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  3. Java多线程学习笔记(一)——多线程实现和安全问题

    1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...

  4. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  5. Java多线程学习笔记--生产消费者模式

    实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...

  6. java 多线程学习笔记

    这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...

  7. Java 多线程学习笔记:生产者消费者问题

    前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...

  8. java多线程学习笔记(七)

    volatile关键字 关键字volatile的主要作用是使变量在多个线程间可见. public class PrintString { private boolean isContinue = tr ...

  9. java多线程学习笔记(四)

    上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...

随机推荐

  1. 设置tabBar、使用第三方插件和自定义组件使用简单实例

    创建小程序项目进入时填写,因需要用上第三方插件,所以要填上开发者的APPID,前往微信公众平台去注册一个账号获取APPID,在设置=>开发设置可以查看相关appid信息 简单思路 底部导航添加三 ...

  2. [android] 新闻客户端引入SlidingMenu

    下载SlidingMenu,https://github.com/jfeinstein10/SlidingMenu 导入library 我们项目右键==>Properties==>Andr ...

  3. CSS学习笔记03 CSS层叠性、继承性、特殊性

    层叠性 所谓层叠性是指多种CSS样式的叠加,也就是说后面设置的样式会层叠(覆盖)之前的样式,层叠性的前提是CSS的选择器的优先级相同,例如,当使用内嵌式CSS样式表定义<p>标记字号大小为 ...

  4. FORM中使用onSubmit="return false"防止表单自动提交,以及submit和button提交表单的区别

    在页面中有多个input type="text"的文本输入框的情况下没有问题,但是当页面中有只有一个文本框的情况下(),就会出现此问题. 后来在form 中添加:onsubmit= ...

  5. mysql5.7.13.zip安装(windows)

    按照我之前安装5.6的安装方法(MySQL免安装版下载与配置)安装5.7的时候出现问题: mysql服务无法启动,服务没有报任何错误

  6. Donsen法则

    “专才”对越来越少的事物了解得越来越多,直到最后他对不存在的事物无所不知: 然而,“通才”对越来越多的事物了解得越来越少,直到他对一切事物一无所知.

  7. JQ面试问题(转载)

    1 你在公司是怎么用jquery的? 答:在项目中是怎么用的是看看你有没有项目经验(根据自己的实际情况来回答) 你用过的选择器啊,动画啊,表单啊,ajax事件等 配置Jquery环境 下载jquery ...

  8. 集合框架三(List和Set的补充(不加泛型))

    List List存放的元素有序,可重复 List list = new ArrayList(); list.add("123"); list.add("456" ...

  9. Jquery中on绑定的一些小坑

    ---恢复内容开始--- 今天我们来说说关于JQuery中事件绑定中on绑定的一些小问题,直接上代码了,大家拷下去就可以用 <!DOCTYPE html> <html lang=&q ...

  10. 【代码笔记】iOS-MBProgressHUD

    一,工程图. 二,代码. AppDelegate.h #import <UIKit/UIKit.h> #import "MBProgressHUD.h" @interf ...