美文网首页技术文Java技术文章
Java中的static和volatile

Java中的static和volatile

作者: F6 | 来源:发表于2015-06-07 22:18 被阅读0次

    《Effective Java》的并发章节讲了一个线程通信问题的例子,非常好的说明了如何由于失误代码导致的线程间通信失败,没有保证一个线程的所作的修改可以被另一个线程获知,也就是活性失败和安全性失败。回头想想,这样的失误(或者根本就不是失误,而是程序员们功力不到家)在工作中太常见了,特别是如果线上系统存在这样的代码,简直就是埋下了地雷。

    作者的例子如下(有改动,但不影响):

    private static boolean stopRequested;
    public static void main(){
    Thread t = new Thread(new Runnable(){
    public void run(){
    int i = 0;
    while(!stopRequested){
    ++i;
    }
    }
    });
    t .start();
    TimeUnit.SECOND.sleep(1);
    stopRequested = true;
    }

    程序员的本意是希望设置 stopRequested = true 后,线程 t 能退出,但并不能达到预期效果。因为类的 static 变量虽然对 Java 的多个对象而言就是唯一的一份拷贝,无论创建了多少个对象。但对于线程,static 变量跟普通变量一样,每个线程自己缓存了一份本地拷贝,t1 改变了变量的值,对于 t2 并不可见,也就是单纯地定义变量为 static 还不够,必须同时声明为 volatile (或者同步锁改变 stopRequested 的值),这样 t1 跟 t2 才能正常通信(针对上述例子而言)。

    这篇文章本意是讲一讲 static 跟 volatile 。so,现在问题来了,如果只声明 stopRequested 为 volatile ,上述的问题还会存在吗?答案是肯定的。定义为 volatile ,跟普通变量一样,是每个线程的一个本地拷贝,线程间并不能感知变量值的变化。声明为 static volatile,会迫使线程每次读取时作为一个全局变量读取。

    推荐阅读
    Volatile Vs Static in java

    相关文章

      网友评论

        本文标题:Java中的static和volatile

        本文链接:https://www.haomeiwen.com/subject/hvzdqttx.html