多线程——Volatile 关键字详解

多线程——Volatile 关键字

一、概念

在前一篇文章中,我们详细介绍了 Java 内存模型,我们可以发现 Java 内存模型都是围绕着在并发过程中如何处理原子性、可见性和有序性三个特征来建立的,简单回顾一下为什么会产生这三个特性:

  • 原子性:比如一段代码运行在服务器,有一段代码会被所有线程访问,每一个线程都会修改里面的共享变量值,为了保证一个线程在修改的时候,其他的线程不会进来捣乱,就引入了原子性的概念,保证原子性的手段最常用的就是锁机制
  • 可见性:我们知道内存分为工作内存和主内存,每个线程都有其独占的工作内存,所有线程共享主内存;可见性就是当一个线程修改了共享内存的值时,其他线程都能够立即得知这个修改
  • 有序性:硬件层面由于为了压榨速度超快的 CPU,引入了 CPU 的乱序执行操作优化,映射到 Java 中就是指令重排序;然后有些地方指令重排序会产生问题,所以需要限制指令重排序,这就是有序性

其中原子性主要由锁机制来保证,锁机制同样也能保证可见性和有序性,这些我们后面会详细讲。本篇文章中我们主要来讲保证可见性和有序性的一种轻量级的手段—— Volatile 关键字


关键字 Volatile 可以说是 JVM 提供的最轻量级的同步机制,但是开发中基本不使用 Volatile,一来并发情况下最需要保证原子性, Volatile 并不能保证原子性;二来 Synchronized 比较全面而且效率也并不会太低于 Volatile,所以普遍都是使用 Synchronized 作为同步手段

不过理解了 Volatile,就会对内存模型和多线程操作的其他特性就会有更深的理解

二、Volatile保证可见性

当一个变量被 volatile 修饰之后,就能够保证此变量对所有的线程的可见性——当一个线程修改了这个变量的值,新值对于其他线程都是立即得知的

普通变量并不能保证这一点,普通变量的值在线程间传递时据需要通过主内存来完成;比如线程 A 修改了一个普通变量的值,然后向主内存进行回写,另外一条线程 B 只有在线程 A 完成了回写之后再对主内存进行读取操作,新变量值才会对线程 B 可见

Volatile 变量对于所有线程都是立即可见的,对 Volatile 变量的所有写操作都能立即反映到其他线程之中,但是基于 volatile 变量的运算在并发情况下并不是线程安全的(不能保证原子性);这句话是什么意思呢?来分析下面的示例代码:

public class VolatileTest {
   
    public static volatile int race = 0;

    public static void increase(){
   
        race++
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值