zoukankan      html  css  js  c++  java
  • (Java 多线程系列)java volatile详解

      在前面的文章里面介绍了synchronized关键字的用法,这篇主要介绍volatile关键字的用法。

      Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其它线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其它内存操作一起重排序。Volatile变量不会被缓存在寄存器或者其它对处理器不可见的地方,因此在读取volatile类型的变量时,总会返回最新写入的值。

    volatile boolean asleep;
    while(!asleep){
        //do something
    }

         volatile变量通常用做某个操作完成、发生中断或者状态的标志。虽然volatile变量使用很方便,但是存在一些局限性:volatile的语义不足以确保递增操作(count++)的原子性,除非你能确保只有一个线程对变量执行写操作。

      volatile与加锁机制的主要区别是:加锁机制既可以确保可见性又可以确保原子性,而volatile变量只有确保可见性

    下面以一个实例来说明使用volatile变量作为状态标志在多线程里面的使用。

    public class VolatileTest{
        volatile boolean mFlag = false;
        public static void main(String[] args) { 
             final VolatileTest mVolTest = new VolatileTest(); 
             Thread t1 = new Thread(new Runnable() {
                public void run() { 
                     while(!mVolTest .mFlag ){
                        System.out.println("Working ...");
                        try {  
                           Thread.sleep(1000);  
                        } catch (InterruptedException ie) { 
                           // 
                        } 
                    }
                } 
             }, "t1"); 
             Thread t2 = new Thread( new Runnable() {
                public void run() { 
                    try {  
                           Thread.sleep(3000); //3秒后停止线程t1
                           mVolTest.mFlag = true;
                        } catch (InterruptedException ie) { 
                           // 
                        } 
                } 
             }, "t2"); 
             t1.start(); 
             t2.start(); 
        } 
    }  

      当且仅当满足以下所有条件时,才应该使用volatile变量

      a)对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值

      b)该变量不会与其它状态变量一起纳入不变性条件中

      c)在访问变量时不需要加锁

  • 相关阅读:
    动态代理练习2全站压缩流输出[response动态代理]
    动态代理练习3自定义数据库连接池[connection动态代理]
    类加载器
    Mysql中的数据类型对应于Java中什么数据类型
    使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法
    动态代理练习1全站字符编码过滤[request动态代理]
    用cocos2dx将helloworld实现出来了
    多线程的自动管理(线程池)
    互斥对象
    多线程的自动管理(定时器)
  • 原文地址:https://www.cnblogs.com/adm1989/p/3293189.html
Copyright © 2011-2022 走看看