volatile关键字理解

1.JMM层面

  • volatile关键字理解_第1张图片
  •  每个线程从主内存中读取数据,读入自己的本地工作内存进行相应的修改,每个线程的本地工作内存相互独立的。因此这就可能造成一个线程读取内存的数据进行的相应的修改,但是没有及时的写入内存,造成其他线程读取到过时的数据,因此有数据不一致性问题。为了解决这个问题,我们可以使用volatile来定义该变量。

2.特性

  • 可见性:一个线程修改了全局变量的值以后,其他线程也可见。实现机制是通过MESI协议,读的时候:把Cache里面的数据读取到寄存器中;写的时候:将volatile修饰的变量的cache line无效,CPU要访问这个变量,直接从内存中读取。
  • 防止指令重排-有序性:在代码编译阶段和字节码指令优化阶段,代码会被重排序,代码最终执行的顺序可能不是我们程序写的顺序,因此有可能会导致程序出错。如果不想指令发生重排,我们可以使用volatile关键字,代码里面volatile修饰的变量上面部分的代码一定先于其后面部分的代码执行。

3.DCL(Double Checking Locking)

  • package com.sap.leo;
    
    public class DoubleCheckingLocking {
        private volatile static DoubleCheckingLocking instance;
        private DoubleCheckingLocking()
        {
    
        }
    
        public DoubleCheckingLocking getInstance()
        {
            if(null == instance) {
                synchronized (instance)
                {
                    if(null == instance)
                    {
                        instance = new DoubleCheckingLocking();
                    }
                }
            }
            return instance;
        }
    }
    

     

3.与sychronized区别

  • 原子性:sychronized具有原子性,volatile不具备
  • 可见性:都具有
  • 有序性:都具备
  • volatile只能修饰变量,synchronized能够修饰方法获取代码块;synchronized包括偏向锁,轻量级锁,自旋锁,重量级锁等;synchronized底层使用字节码指令monitorenter和monitorexit;

你可能感兴趣的:(Java,基础知识,volatile)