java中volatile关键字

来源:互联网 发布:centos php版本切换 编辑:程序博客网 时间:2024/05/18 00:41
java中


volatile关键字的作用是保证可见性,但是不保证原子性。

可见性:在java多线程读写数据的时候,有两块区域,一块是内存区,另一块是线程内存缓冲区,当多线程访问资源时,是先将资源在内存中拷贝到内存缓冲区。volatile可见性是指保证当线程里对资源副本进行修改时,资源主动保存到内存库。


原子性:是指操作的不可分割性。比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a + 1;是可分割的,所以他不是一个原子操作。


volatile最典型的应用应该是单例模型中的双重检查索机制,如下面的例子。


public class Singleton {
 private static Singleton uniqueInstance;
 private Singleton(){
    }
  public static Singleton getInstance(){
         if(uniqueInstance == null){ //#1
             synchronized(Singleton.class){ //#2
                 if(uniqueInstance == null){ //#3
                     uniqueInstance = new Singleton(); //#4
                     System.out.println(Thread.currentThread().getName() + ": uniqueInstance is initalized..."); //#5.1
                 } else {
                     System.out.println(Thread.currentThread().getName() + ": uniqueInstance is not null now..."); //#5.2
                 }
             }
         }
         return uniqueInstance;
     }

}


接下来是TestSingleton类

public class TestSingleton {
    public static void main(final String[] args) throws InterruptedException {
        for (int i = 1; i <= 100000; i++) {
            final Thread t1 = new Thread(new ThreadSingleton());
            t1.setName("thread" + i);
            t1.start();
        }
    }

    public static class ThreadSingleton implements Runnable {
        @Override
        public void run() {
            Singleton.getInstance();
        }
    }
}



如果对于单例对象uniqueInstance不增加violatile关键字,

则有可能出现初始化执行两次的问题。