美文网首页
Java语言中,关键字Volatile的使用你清楚吗?

Java语言中,关键字Volatile的使用你清楚吗?

作者: 小二上酒8 | 来源:发表于2022-11-23 10:56 被阅读0次

前言

在Java开发中,若仅为读写一个或两个对象就使用同步锁处理,会增大程序内存开销,而volatile关键字就可以很好地解决这个问题。声明一个对象为volatile,则Java编译器和虚拟机就会清楚该对象是可能被另一个线程并发更新。不过在了解volatile之前熟悉一下并发编程中的三个特性:原子性,可见性,有序性。

1.并发编程三个特性:原子性,可见性,有序性

  • 原子性
    对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行。
x = 10;        // 1
y = x;         // 2
x++;           // 3
x = x + 1;     // 4
复制代码

以上1是原子性操作,其他3个语句均不是原子性操作。
2实际上包含2个操作,先要读取x的值,再将x的值写入内存,读取x的值以及 将x的值写入内存这2个操作都是原子性操作,但合起来就不是原子性操作啦。
x++和 x = x+1 包括3个操作:读取x的值,进行加1操作,写入新值。换句话说,只有简单的读取、赋值才是原子操作。

  • 可见性
    指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程马上就能看到。

  • 有序性
    Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

关键字volatile

被volatile修饰共享变量,有两种含义

  • 保证了不同线程对这变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
  • 禁止进行指令重排序。

volatile能否保证原子性?

自增操作不是原子性操作,而且volatile也无法保证对变量的任何操作都是原子性的。

volatile能否保证有序性?

volatile关键字能禁止指令重排序,所以能在一定程度上保证有序性。
volatile禁止指令重排序有两层意思:

  • 当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;
  • 在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。

总结

与锁相比,Volatile 变量是一种非常简单但同时又非常脆弱的同步机制,在某些情况下将提供优于锁的性能和伸缩性。在某些情况下可以使用 volatile 代替 synchronized 来简化代码。

相关文章

网友评论

      本文标题:Java语言中,关键字Volatile的使用你清楚吗?

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