一.happens-before原则

同一个线程中的,前面的操作 happens-before 后续的操作。(即单线程内按代码顺序执行。但是,在不影响在单线程环境执行结果的前提下,编译器和处理器可以进行重排序,这是合法的。换句话说,这一是规则无法保证编译重排和指令重排)。

1. 监视器上的解锁操作 happens-before 其后续的加锁操作。(Synchronized 规则)

2. 对volatile变量的写操作 happens-before 后续的读操作。(volatile 规则)

3. 线程的start() 方法 happens-before 该线程所有的后续操作。(线程启动规则)

4. 线程所有的操作 happens-before 其他线程在该线程上调用 join 返回成功后的操作。

5. 如果 a happens-before b,b happens-before c,则a happens-before c(传递性)

二.volatile关键字的作用

Volatile关键字主要用于保证内存可见性和顺序性:

1.volatile修饰的变量可以保证一个线程对该变量的写happens-before 一个线程对该变量的读

2.Volatile可以用来修饰long和double类型的变量使其以原子方式执行

3.Volatile在双重检查加锁的单例模式中的应用,可以防止重排序

三.volatile关键字的实现原理

在java代码编译成字节码时会在volatile修饰的共享变量进行写操作的时候会多出Lock前缀的指令。

我们知道为了提高处理速度,CPU不直接和内存进行通信,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完不知道何时会写回内存。如果对声明了volatile的变量进行写操作,JVM就会向CPU发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是,就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题。所以,在多处理器下,为了保证各个CPU的缓存是一致的,就会实现缓存一致性协议,每个CPU通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前CPU的缓存行设置成无效状态,当CPU对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存里

  1. Lock前缀的指令会引起CPU缓存写回内存;
  2. 一个CPU的缓存回写到内存会导致其他处理器的缓存失效;
  3. 当CPU发现本地缓存失效后,就会从内存中重读该变量数据,即可以获取当前最新值。

这样针对volatile变量通过这样的机制就使得每个线程都能获得该变量的最新值

volatile相关的理解就写到这里,如果大家还想详细的了解volatile可以查阅相关资料或者私信我进行交流。

并发是java中无法避免的问题,基本上java面试都会涉及一些并发相关的问题,尤其是互联网公司一定会问到,今天就先写到了这里,下次准备把并发中相关的锁和并发集合的知识整理一下分享给大家,如果喜欢记得关注我【不爱八阿哥】,有什么问题也可以私信交流,让我们共同进步。

来源:https://www.toutiao.com/i6656572928701760004/

java面试总躲不过的并发(二):volatile原理 + happens-before原则的更多相关文章

  1. java面试总躲不过的并发(一): 线程池ThreadPoolExecutor基础梳理

    本文核心:线程池ThreadPoolExecutor基础梳理 一.实现多线程的方式 1.继承Thread类,重写其run方法 2.实现Runnable接口,实现run方法 3.实现Callable接口 ...

  2. Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  3. Java面试知识点之线程篇(二)

    前言:接上篇,这里继续对java线程相关知识点进行总结. 1.notify和notifyall的区别 notify()方法能够唤醒一个正在等待该对象的monitor的线程,当有多个线程都在等待该对象的 ...

  4. Java面试不得不知的程序(二)

    [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 斐波那契数列:前面相邻两项之和,构 ...

  5. 死磕Java面试系列:深拷贝与浅拷贝的实现原理

    深拷贝与浅拷贝的问题,也是面试中的常客.虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝.其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入 ...

  6. 【Java面试】Zookeeper中的Watch机制的原理?

    一个工作了7年的粉丝,遇到了一个Zookeeper的问题. 因为接触过Zookeeper这个技术,不知道该怎么回答. 我说一个工作了7年的程序员,没有接触过主流技术,这不正常. 于是我问了他工资以后, ...

  7. 【Java面试】请说一下ReentrantLock的实现原理?

    一个工作了3年的粉丝私信我,在面试的时候遇到了这样一个问题. "请说一下ReentrantLock的实现原理",他当时根据自己的理解零零散散的说了一些. 但是似乎没有说到关键点上, ...

  8. Java面试知识点之线程篇(一)

    前言:在Java面试中,一定会遇到线程相关问题,因此笔者在这里总结Java中有关线程方面知识点,多数从网上得来(文中会贴出主要参考链接),有些也是笔者在面试中所遇到的问题,如有错误,请不吝指正.主要参 ...

  9. Java线程池使用和分析(二) - execute()原理

    相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...

随机推荐

  1. C语言:开平方根sqrt程序02

    #include <stdio.h> int sqrt01(int x); void main(void){ int x=49,y; y=sqrt01(x); if(y<0) pri ...

  2. 指导手册 07 安装配置HIVE

    指导手册 07 安装配置HIVE   安装环境及所需安装包: 1.操作系统:centos6.8 2.四台虚拟机:master :10.0.2.4, slave1:10.0.2.5,slave2:10. ...

  3. linux 清理几天前的日志或文件

    执行清理1天前的 war 包 find . -ctime +1 -name "*.war" -exec rm {} \;

  4. 【转】Android-Input 触控笔

    https://source.android.com/devices/accessories/stylus 触控笔 Android 6.0 及更高版本支持蓝牙 (BT).蓝牙低功耗 (BTLE) 或 ...

  5. MySQL存储过程中实现执行动态SQL语句

    sql语句中的任何部分都可以作为参数. DROP PROCEDURE if exists insertdata; delimiter //CREATE PROCEDURE insertdata(IN ...

  6. Python成长之路【第二篇】Python基础之数据类型

    阅读目录 简介 1 什么是数据? x=10,10是我们要存储的数据 2 为何数据要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示 3 数据类型 数字(整形,长整形,浮点型 ...

  7. Vue开发爬坑记录

    1.使用eslint代码检查时,常见的的错误: 1.1 Expected indentation of 0 spaces but found 1 前面的空格个数不对.应该不能有空格. 1.2 Stri ...

  8. Some notes in Stanford CS106A(2)

    1.Local variable(local) ex. int i = 0; factorial(i); the "i" outside the method factorial( ...

  9. WPF-在Grid中编程添加控件

    摘要: 在Grid中编程添加控件,布局控件的位置用到的代码是: gridLayout.Children.Add(textblock); Grid.SetRow(textblock, ); Grid.S ...

  10. QWaitConditioin的思考1

    16:50:392017-03-31 本文章为原创,如若引用请指明出处,否则追责. 以 生产.消费者的例子说明 #include <QtCore/QCoreApplication>#inc ...