zoukankan      html  css  js  c++  java
  • 谈谈对volatile关键字的理解

    1. volatile的特性

    volatile是Java语言提供的一种轻量级的同步机制,用来确保将变量得更新操作通知到其它线程。具备三种特性:

    • 保证变量的可见性
    • 对于volatile修饰的变量进行单次读/写操作可以保证原子性,对于i++这样的多次操作不保证原子性
    • 防止指令重排(通过在指令序列中插入内存屏障来禁止特定类型的处理器重排序)。

    2. volatile关键字和synchronized关键字的区别

    区别可以从以下四点阐述:

    • volatile关键字是线程同步的轻量级实现,其性能比synchronized关键字好。但是volatile关键字只能修饰变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JDK1.6之前是一种重量级锁,在1.6之后进行了一系列的优化(主要是为了减少获得锁和释放锁带来的性能消耗而引入偏向锁和轻量级锁使得效率有所提升),实际中使用synchronized的场景相对较多;
    • 多线程情况下访问volatile关键字修饰的变量不会造成阻塞,而synchronized关键字可能会造成阻塞;
    • volatile可以保证变量的可见性,但不能完全保证数据操作的原子性,而synchronized技能保证变量可见性也能保证原子性;
    • volatile关键字主要用于解决变量在多个线程之间的可见性问题,而synchronized关键字解决的是多个线程之间访问资源的同步性。

    3. 使用volatile关键字的场景

    单例模式(双检锁DCL)

    public class Singleton {
        
        private volatile static Singleton singleton;
        
        private Singleton() {
        }
        
        public static Singleton getSingleton() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    

    使用volatile关键字修饰singleton,防止指令重排。如果不加volatile关键字,则会出如下问题:在执行if (singleton == null)判断时,有可能singleton对象正在初始化的过程中还未完成,因此会通过双重检查,然后又进行一次singleton对象的初始化,从而导致出现多个实例。

  • 相关阅读:
    Page6:关于能控性、能观性、能测性及其判据(1)[Linear System Theory]
    Page5:状态转移矩阵及性质、连续线性系统离散化及其性质[Linear System Theory]
    java线程学习之notify方法和notifyAll方法
    java线程学习之wait方法
    java线程学习之synchronized关键字
    java线程学习之Sleep方法
    java线程学习之线程创建
    用javaScript获取页面元素值
    用javaScript对页面元素进行显示和隐藏
    JDBC工具类
  • 原文地址:https://www.cnblogs.com/chiaki/p/13499714.html
Copyright © 2011-2022 走看看