美文网首页
volatile的可见性和有序性

volatile的可见性和有序性

作者: Brook_liu | 来源:发表于2019-12-11 08:28 被阅读0次

什么是volatile的可见性?

首先要从JMM内存模型说起,每一个线程都会有自己的工作内存,而线程要访问主内存的共享变量时,是会将变量对象拷贝一份变量副本到工作内存。

对于普通共享变量,线程读取的变量值是工作内存的副本,修改后并非立即写入主内存,因此在多线程并发的情况,一个线程修改了变量值后,另一个线程可能依然读取的是自己工作内存的变量副本,而没有读到另一个线程修改后的变量值。因此就会造成并发情况下出现逻辑控制上的问题。

对于volatile修饰的变量,线程在修改工作内存的变量副本时,会置其他线程工作内存中该变量副本为无效,并在修改后立即写入主内存。而其他线程在发现工作内存中变量副本置为无效时会去主内存读取最新的值,这个过程会去等待修改线程先写入主内存。因此volatile修饰变量后,线程的读写效率会降低。

volatile修饰变量后,可能引入的问题:因为volatile修饰后,变量修改后会立即写入到主内存。所以可能存在一个线程内已经对该变量判空,但是因为另一个线程置空,导致本线程更容易发生空指针异常。

volatile A a = new A();

线程1

a = null;

线程2

if(a != null){

a.b();// 可能空指针异常

}

什么是volatile的有序性?

说到有序性就不得不说说指令重排序,什么是指令重排序?简单的说就是系统为了优化代码执行效率,会打乱代码先后顺序并可能先执行后面的代码。
举个例子:

int a=1; // 代码1
int b =2;// 代码2
int c =a+b; // 代码3

代码2可能会比代码1先执行,但是代码3不会比前面的先执行,因为这样会出错,代码3依赖前两者的结果。所以系统在保证逻辑正确的情况下会对代码重排序。

而volatile修饰的变量就可以禁止指令重排序。
举个例子:

//变量c是volatile类型
int a =1;//代码1
boolean flag =true; //代码2
c =2;//代码3
a =2;//代码4
flag =false; //代码5

代码1和代码2可能重排序,代码4和代码5可能重排序,但是代码3不会先于代码1和2执行,也不会在代码4和5之后执行。

相关文章

  • 吃透Java并发:volatile是怎么保证可见性的

    前言 volatile关键字能够保证可见性和有序性,但是volatile为什么能够保证可见性和有序性?为什么vol...

  • volatile关键字解析

    Volatile关键字有什么作用?Volatile关键字可以保证变量的可见性和有序性 什么是可见性和有序性?要搞清...

  • volatile关键字

    在并发编程中,常遇到的三个问题:原子性,可见性,有序性。volatile可解决可见性和有序性的问题。 1、可见性 ...

  • 2019-07-10 平安壹钱包面经

    原子性、有序性和可见性的理解 volatile关键字对于有序性和可见性的保障 什么事可见性,这个我答的不是很好,说...

  • Java 线程安全问题

    1. 线程安全问题分为多个层面 可见性 volatile, Synchronized 有序性 volatile, ...

  • Java 中的volatile 关键字

    并发编程的三个特性 原子性 有序性 可见性 Java 中的volatile 关键字能保证可见性和有序性,但是无法保...

  • volatile

    volatile有什么用(有序性)? volatile保证内存可见性和禁止指令重排。 用一句话说明volatile...

  • 2详解Happens-Before原则(解决并发编程可见性、有序

    并发的三个特性:原子性,可见性,有序性 可见性 -> 缓存有序性 -> 编译优化 volatile 使用 介绍 v...

  • volatile关键字

    1、概述 volatile保证多线程下变量可见性和有序性的问题,不保证原子性。 volatile不是并发安全的,因...

  • Volatile关键字从理解到实操,源码实例深度剖析

    谈到并发编程 ,必知晓并发三要素 :原子性、可见性、有序性。而 Volatile 涉及了可见性与有序性,是轻量级的...

网友评论

      本文标题:volatile的可见性和有序性

      本文链接:https://www.haomeiwen.com/subject/ndyngctx.html