volatile

volatile是Java并发编程中的轻量级同步机制,确保共享变量的可见性和禁止指令重排序。然而,它不能保证原子性,因此在多线程环境下可能会出现线程安全问题。例如,对于计数器的增加操作,即使使用volatile,仍可能出现线程安全问题,需要配合synchronized关键字来确保同步。volatile通过内存屏障来防止指令重排序,确保变量更新的正确次序。在某些特定场景,如控制shutdown变量,volatile可以实现线程安全。理解volatile的工作原理对于优化并发代码至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

volatile是JVM提供的轻量级同步机制

  1. 保证被volatile修饰的共享变量对所有线程总是可见的。当一个线程修改了一个被volatile修饰的共享变量时,其他线程能够立即感知到变动
  2. 禁止指令重排序优化。

 

使用volatile修饰的变量仍然会存在线程安全的问题

如下程序所示,两个线程可能在同一时间读取value值为同一值,对value值进行加1的操作,就会导致线程安全的问题。

 

要解决线程安全的问题,就要在increase方法前加上synchronized关键字。由于synchronized可以实现线程同步,所以可以去掉value的volatile修饰符。

 

使用volatile实现线程安全的场景

使用volatile修饰的shutdown变量对其他线程立即可见,从而实现了线程安全。

 

Volatile变量为何立即可见?

当写一个volatile变量时,JVM会把该线程对应的工作内存中的共享变量值刷新到主内存中;当读取一个volatile变量时,JVM会把该线程对应的工作内存置为无效,那么线程就只能从主内存中重新读取共享变量的值。

 

Volatile如何禁止指令重排优化

内存屏障

  1. 保证特定操作的执行顺序

通过插入内存屏障指令进制在内存屏障前后的指令执行重排序优化

  1. 保证某些变量的内存可见性

强制刷新各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本

Volatile就是通过内存屏障来实现其在内存中的可见性和禁止重排优化

 

例子

 

在创建instance时,分为三步

 

由于第二步和第三步不存在数据依赖的关系,这时就会出现指令重排序问题

 

在多线程情况下就会出现问题。

解决的方式:

使用volatile修饰instance变量,来禁止instance变量被执行指令重排序

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值