一、基本概念

先补充一下概念:Java并发中的可见性与原子性

可见性:

可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。

可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修饰的变量,就会具有可见性。volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。所以对其他线程是可见的。但是这里需要注意一个问题,volatile只能让被他修饰内容具有可见性,但不能保证它具有原子性。比如 volatile int a = 0;之后有一个操作 a++;这个变量a具有可见性,但是a++ 依然是一个非原子操作,也就这这个操作同样存在线程安全问题。

原子性:

原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。java的concurrent包下提供了一些原子类,我们可以通过阅读API来了解这些原子类的用法。比如:AtomicInteger、AtomicLong、AtomicReference等。

下面内容摘录自《Java Concurrency in Practice》:

下面一段代码在多线程环境下,将存在问题。

/**

*@authorzhengbinMac */

public classNoVisibility { private static booleanready; private static intnumber; private static class ReaderThread extendsThread { @Override public voidrun() { while(!ready) { Thread.yield(); } System.out.println(number); } } public static voidmain(String[] args) { newReaderThread().start(); number = 42; ready = true; } }

NoVisibility可能会持续循环下去,因为读线程可能永远都看不到ready的值。甚至NoVisibility可能会输出0,因为读线程可能看到了写入ready的值,但却没有看到之后写入number的值,这种现象被称为“重排序”。只要在某个线程中无法检测到重排序情况(即使在其他线程中可以明显地看到该线程中的重排序),那么就无法确保线程中的操作将按照程序中指定的顺序来执行。当主线程首先写入number,然后在没有同步的情况下写入ready,那么读线程看到的顺序可能与写入的顺序完全相反。

在没有同步的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整。在缺乏足够同步的多线程程序中,要想对内存操作的执行春旭进行判断,无法得到正确的结论。

这个看上去像是一个失败的设计,但却能使JVM充分地利用现代多核处理器的强大性能。例如,在缺少同步的情况下,Java内存模型允许编译器对操作顺序进行重排序,并将数值缓存在寄存器中。此外,它还允许CPU对操作顺序进行重排序,并将数值缓存在处理器特定的缓存中。

二、Volatile原理

Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会讲该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。

在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。

当对非volatile变量进行读写的时候,每个线程先从内存拷贝变量到CPU缓存中。如果计算机有多个CPU,每个线程可能在不同的CPU上被处理,这意味着每个线程可以考虑到不同的CPU cache中。

而声明变量是volatile的,JVM保证了每次读变量都从内存中读,跳过CPU cache这一步。

java中volatile_Java中Volatile关键字详解相关推荐

  1. Java并发编程:volatile关键字详解

    volatile关键字两大特性:线程可见性/禁止指令重排序 原理:由jvm实现的一条汇编质量lock 要知道为什么会能保证线程的可见性,先要了解jmm的原子操作 假设一个变量initFlag默认为fa ...

  2. 并发编程系列之volatile关键字详解

    并发编程系列之volatile关键字详解 1.volatile是什么? 首先简单说一下,volatile是什么?volatile是Java中的一个关键字,也是一种同步机制.volatile为了保证变量 ...

  3. 教妹学Java(十九):continue 关键字详解

    你好呀,我是沉默王二,是<Web 全栈开发进阶之路>的作者,CSDN 2019 年度的博客之星.<教妹学 Java>是一套非常有趣的付费专栏,除了继续保持幽默风趣的行风风格,我 ...

  4. java中实现具有传递性吗_Java中volatile关键字详解,jvm内存模型,原子性、可见性、有序性...

    一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...

  5. java volatile 基本类型_Java中Volatile关键字详解(转)

    一.基本概念 先补充一下概念:Java 内存模型中的可见性.原子性和有序性. 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其 ...

  6. C/C++中volatile关键字详解

    1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 "The ...

  7. Java volatile关键字详解

    1.关于volatile volatile是Java语言中的关键字,用来修饰会被多线程访问的共享变量,是JVM提供的轻量级的同步机制,相比同步代码块或者重入锁有更好的性能.它主要有两重语义,一是保证多 ...

  8. volatile 关键字详解

    volatile,可以当之无愧的被称为Java并发编程中"出现频率最高的关键字",常用于保持内存可见性和防止指令重排序. 保持内存可见性 内存可见性(Memory Visibili ...

  9. volatile关键字详解

    文章目录 1 volatile作用 2 volatile非原子的特性 3 原子类也并不完全安全 4 原子类和volatile区别 1 volatile作用 volatile关键字的主要作用是使变量在多 ...

  10. C语言volatile关键字详解

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

最新文章

  1. Nginx搭建负载均衡集群
  2. 【青少年编程】【三级】 合作画画
  3. mybatis对mapper.xml的解析(一)
  4. IIR+全通滤波器实现相位平衡_matlab仿真
  5. JAVA传入一个字符串,返回一个字符串中的大写字母
  6. Youtube深度学习推荐系统
  7. window document
  8. NumPy Beginner's Guide 2e 带注释源码 三、熟悉 NumPy 常用函数
  9. java垃圾收集器zgc_java虚拟机ZGC垃圾收集器的实现方法
  10. 神策数据:打造趁手好用的标签用户画像系统(附PPT下载链接)
  11. Oracle——集合运算
  12. NOIP2016换教室 BZOJ 4720
  13. antd的timePicker.RangePicker设置结束时间不可早于开始时间
  14. linux 编辑文件出现E45readonly option is set (add! to .....)
  15. Leetcode(347)——前 K 个高频元素
  16. C# winform cefsharp 截取网页元素图片
  17. 在proteus中的排阻的查找_PROTEUS中这个排阻怎么找到?
  18. Erlang程序设计笔记---(第三节 Erlang的基本概念)
  19. php think-queue队列的安装使用和Supervisor的安装配置和使用
  20. 2. Hadoop的安装(这你都没装好,我就服了)

热门文章

  1. 在vi或vim上查找字符串
  2. 计算机专业学位英语试题,(荐)2015年最新电大学位英语考试精篇复习资料 小抄版.doc...
  3. linux 软件装到hone,如何在Linux系统安装Apollo
  4. 看你的样子对Vue研究挺深的,我司招Vue,五险一金有兴趣吗?
  5. 一款让你轻松在IDEA画图的插件!
  6. 皮一皮:有的人自以为有小聪明...
  7. 退休是不可能的,90岁还要继续干!
  8. 链家前DBA判刑7年!你还敢不敢删库?
  9. 又一个智商税产品“路由器防辐射笼”,信号都没了,还能火爆全网...
  10. 大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?