volatile关键字理解

这里的“可见性”指的是,当对一个变量修改后,新值对于其他线程是立即可见的,注意这里的立即可见,并不是说其他线程能监听到变量值修改,而是说修改后的值能立即同步到主内存中(稍后介绍Java内存模型),保证其他线程能读取到的一定是最新值。什么是指令重排优化呢,Java源代码最终会编译成计算机能识别的机器码指令,为了提高执行效率,编译器和处理器可能会对指令进行优化重新排序,导致实际上指令执行的顺序可能会和源代码中想表达的顺序不一致。到此如果能轻松的理解上面两句话的,可以跳过本文。
摘要由CSDN通过智能技术生成

一、volatile关键字的意义

volatile关键字是Java虚拟机提供的最轻量级的线程间同步机制,我们很容易在书籍或网络上了解到volatile关键字的作用,主要有两点:

1、当一个变量被volatile修饰时,将保证此变量对所有线程的可见性。 这里的“可见性”指的是,当对一个变量修改后,新值对于其他线程是立即可见的,注意这里的立即可见,并不是说其他线程能监听到变量值修改,而是说修改后的值能立即同步到主内存中(稍后介绍Java内存模型),保证其他线程能读取到的一定是最新值。

2、使用volatile修饰的变量能禁止指令重排优化。 什么是指令重排优化呢,Java源代码最终会编译成计算机能识别的机器码指令,为了提高执行效率,编译器和处理器可能会对指令进行优化重新排序,导致实际上指令执行的顺序可能会和源代码中想表达的顺序不一致。

到此如果能轻松的理解上面两句话的,可以跳过本文。如果不能理解,下面我们将通过代码来验证上面的定义,在此之前,先简单介绍下Java的内存模型和相关概念,有助于更好的理解上述内容。

二、Java内存模型

Java内存分为主内存和工作内存。所有变量都存在主内存中,每个线程都有自己的工作内存(可理解为缓存,实际上底层实现大概就是寄存器或高速缓存),线程的工作内存中将会拷贝主内存中变量的副本,所有的读写等操作都在工作内存中完成,线程的工作内存不能被其他线程访问。

线程、工作内存、主内存的关系如下图:

Java内存模型

这里介绍下Java内存操作的三个基本概念: 原子性、可见性、有序性。这里只是简单介绍,有兴趣自行查阅资料。

原子性,可以理解为对某一块内存的操作不可再细分,也就是中间不能再插入其他操作。符合原子性的操作称为原子操作,Java内存模型定义下列8种原子操作:
lock/unlock:将主内存的变量锁定/解锁为一条线程独占状态,例如使用synchronized关键字标识的代码块。
read、load:read将主内存中的变量值传输到线程工作内存中,load将得到的变量值存入工作线程的变量副本。
use、assign:使用和赋值。
store、write:store将工作内存中的副本变量值传送到主内存,随后write操作写入主内存。
例如有一个变量A和B,表达式A = B完整的操作,可能会是read A、read B、load B、load A、use B‘、assign A’(=B‘)、store A’、write A。这里只是辅助理解,实际操作可能更为复杂,读、写操作中间是可以插入其他操作的。

可见性,上面已经给出过解释,就是当修改一个共享变量时,其他线程能立即“主动”获得最新值,也就是保证拿到的一定是最新的值。

有序性,在单个线程内,所有的操作都是有序的,程序会按照代码的顺序执行。但是多个线程并发时,因为有指令重排序,所以会影响指令的执行顺序。

三、代码举例

1、volatile可见性

首先“可见性”很容易被我们误解为“volatile修饰的变量是线程安全的”,我们用下面的代码验证下:

public static volatile int count = 0;

public static void add() {
   
    count++;
}

public static void main(String[] args) {
   
    int defCount = Thread.activeCount();
    // 10个子线程
    for (int i = 0; i < 10; i++
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值