基本内存屏障

  处理器支持那种内存重排序,就会提供能够禁止相应内存重排序的的指令,这些指令就被成为基本内存屏障: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. ASP.NET MVC实现剪切图片

    开发需要,我们需要对某一张图片进行剪切.就是说,获取图片某一区域.下面Insus.NET教大家轻便容易实现它. 首先写好一个处理函数,它建在MVC应用程序结构Utilities目录下: 准备好一张图片 ...

  2. (微信小程序)一 : 初识微信小程序

    首先看过angularjs的同学们在看微信小程序的创始文件应该不算很陌生吧. 需要看的 先是文件目录 看完这个目录..得知 ( 一 )    pages   他存放于多个页面 如 index ,log ...

  3. 基于hive的日志分析系统

    转自 http://www.cppblog.com/koson/archive/2010/07/19/120773.html           hive 简介         hive 是一个基于  ...

  4. Android照片墙-多图加载

    http://blog.csdn.net/guolin_blog/article/details/9526203 照片墙这种功能现在应该算是挺常见了,在很多应用中你都可以经常看到照片墙的身影.它的设计 ...

  5. DataTable的数据或表结构复制

    把datatable的结构全部数据或部分数据复制到一个新的datatabledatatable复制表结构:我们可以使用.clone()方法: DataTable oldDT = GetDataTabl ...

  6. django—xadmin中集成富文本编辑器ueditor

    一.安装 pip命令安装,由于ueditor为百度开发的一款富文本编辑框,现已停止维护,如果解释器为python2,则直接pip install djangoueditor 解压包安装,python3 ...

  7. python-外观模式

    源码地址:https://github.com/weilanhanf/PythonDesignPatterns 说明: 外观模式又叫做门面模式.在面向对象程序设计中,解耦是一种推崇的理念.但事实上由于 ...

  8. js-ES6学习笔记-Class(4)

    1.Object.getPrototypeOf方法可以用来从子类上获取父类.因此,可以使用这个方法判断,一个类是否继承了另一个类. 2.super这个关键字,既可以当作函数使用,也可以当作对象使用.在 ...

  9. IDEA项目搭建一——使用Maven创建多模块项目

    废话不多说,直接开始吧,如果有哪里写的不多的,还望指出,谢谢 一.创建空项目EmpayProject File -> New -> Project 二.添加父模块Parent Module ...

  10. flutter .g文件生成不了

    [SEVERE] Conflicting outputs were detected and the build is unable to prompt for permission to remov ...