• java中volatile


      volatile用来修饰变量。Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是synchronized 的一部分。

      首先要介绍几个并发中会用到的概念。

      原子性

      原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

      原子性就像数据库里面的事务一样,他们是一个团队,同生共死。其实理解原子性非常简单,我们看下面一个简单的例子即可:

      i = 0;            ---1
      j = i ;            ---2
      i++;            ---3
      i = j + 1;    ---4

      1—在Java中,对基本数据类型的变量和赋值操作都是原子性操作;
      2—包含了两个操作:读取i,将i值赋值给j
      3—包含了三个操作:读取i值、i + 1 、将+1结果赋值给i;
      4—同三一样

      在单线程环境下我们可以认为整个步骤都是原子性操作,但是在多线程环境下则不同,Java只保证了基本数据类型的变量和赋值操作才是原子性的(注:在32位的JDK环境下,对64位数据的读取不是原子性操作*,如long、double)。要想在多线程环境下保证原子性,则可以通过锁、synchronized来确保。

      volatile是无法保证复合操作的原子性。

      可见性

      可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

      在上面已经分析了,在多线程环境下,一个线程对共享变量的操作对其他线程是不可见的。

      Java提供了volatile来保证可见性。

      当一个变量被volatile修饰后,表示着线程本地内存(working memory)无效,当一个线程修改共享变量后他会立即被更新到主内存(main memory)中,当其他线程读取共享变量时,它会直接从主内存中读取。

      有序性

      有序性:即程序执行的顺序按照代码的先后顺序执行。

      在Java内存模型中,为了效率是允许编译器和处理器对指令进行重排序,当然重排序它不会影响单线程的运行结果,但是对多线程会有影响。

      Java提供volatile来保证一定的有序性。

      java语言规范中,对volatile的描述:volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。在JVM底层volatile是采用“内存屏障”来实现的。

      也就是说,一,保证了可见性,不保证原子性,二,禁止指令重排序。(在执行程序时为了提高性能,编译器和处理器通常会对指令做重排序:编译器重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序;处理器重排序。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障,指令重排序时不能把后面的指令重排序到内存屏障之前的位置)

    //2018.2.13

  • 相关阅读:
    Java学习笔记1---JVM、JRE、JDK
    Java学习笔记2---设置环境变量JAVA_HOME,CLASSPATH,PATH
    第一次博客作业
    2018-2019-2 《Java程序设计》第5周学习总结
    作业四——文法和语言总结与梳理
    作业三——语法书、短语、直接短语、句柄
    作业二——文法和语言
    团队项目-需求分析报告
    团队项目-选题报告
    第一次结对编程作业
  • 原文地址:https://www.cnblogs.com/GoForMyDream/p/8446472.html
Copyright © 2020-2023  润新知