volatile关键字

Java语言为了解决并发程序中存在的原子性、可见性、有序性问题,听过了一些列处理并发的关键字。如synchronized、volatile、final等,上一篇中讲解了synchornizedguan关键字的用法和原理等。在文本中,我们来分析另外一个关键字----volatile。

1:volatile:轻量级同步锁

volatile本身的意思就是“易挥发”的意思,其实就是不稳定的意思。其作用与锁有相同的地方:保证可见性和有序性。不同的是,在原子性方面仅能保证写volatile变量操作的yuan原子性,但没有锁的排他性;其次,volatile关键字的使用不会引起上下文切换(这正是volatile被称为”轻量级“的原因)。

volatile是一个变量修饰符,只能用来修饰变量,无法修饰方法和代码块。其用法比较简单,只需要在可能被多个线程共享的变量前加如该关键字即可。

以一个单例作为其使用Demo

package sync;

public class VolatileDemo {
    private volatile static VolatileDemo volatileDemo;

    private VolatileDemo(){}

    public static VolatileDemo getVolatileDemo(){
        if(volatileDemo == null){
            synchronized (VolatileDemo.class){
                if(volatileDemo == null){
                    volatileDemo = new VolatileDemo();
                }
            }
        }
        return volatileDemo;
    }
}

如以上代码,是一个比较典型的使用双重锁校验的形式实现单例的,其中使用volatile关键字修饰可能被多个线程同时访问到的volatileDemo。

2:volatile可见性

Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次是用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。

3:volatile有序性

volatile可以禁止指令重排,这就保证了代码的程序会严格按照代码的先后顺序执行。这就保证了有序性。被volatile修饰的变量的操作,会严格按照代码顺序执行,load->add->save 的执行顺序就是:load、add、save。

3:volatile与原子性(不能保证的)

线程是CPU调度的基本单位。CPU有时间片的概念,会根据不同的调度算法进行线程调度。当一个线程获得时间片之后开始执行,在时间片耗尽之后,就会失去CPU使用权。所以在多线程场景下,由于时间片在线程间轮换,就会发生原子性问题。

synchronized需要通过字节码指令monitorentermonitorexit来保证原子性,volatile和这两个指令之间是没有任何关系的。

所以,volatile是不能保证原子性的。

4:开销

volatile变量的读、写操作都不会导致上下文切换,因此volatile的开销比锁小。但volatile变量的zh值每次都要从高速缓存或者主内存中读取,无法被暂存在寄存器中,从而无法发挥访问的高效性。

注意:volatile关键字并非锁的替代品,volatile和锁各有其使用条件。volatile更适用于多个线程共享一个状态变量,而后者更适用于多个线程共享一组状态变量。当然在某些情况下,我们可以将多个线程共享的一组状态变量合并成一个对象,用一个volatile变量来引用该对象,从而在该情况下不需要使用锁。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值