说明volatile:此代码是线程安全的吗? [英] illustrating volatile : is this code thread-safe?

查看:174
本文介绍了说明volatile:此代码是线程安全的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用一个例子来说明volatile的用法和重要性,如果省略volatile,它实际上不会给出很好的结果.

I'm trying to illustrate the use and importance of volatile with an example that would really not give a good result if volatile was omitted.

但是我不太习惯使用volatile.以下代码的想法是,如果省略volatile,则会导致无限循环;如果存在volatile,则将是完全线程安全的.以下代码是线程安全的吗?您是否还有其他使用volatile的逼真的简短示例代码,如果没有该示例,则会给出明显不正确的结果?

But I'm not really used to using volatile. The idea of the following code is to cause an infinite loop if volatile is omitted, and be perfectly thread-safe if volatile is present. Is the following code thread-safe? Do you have any other realistic and short example of code that uses volatile and would give an obviously incorrect result without it?

代码如下:

public class VolatileTest implements Runnable {

    private int count;
    private volatile boolean stopped;

    @Override
    public void run() {
        while (!stopped) {
            count++;
        }
        System.out.println("Count 1 = " + count);
    }

    public void stopCounting() {
        stopped = true;
    }

    public int getCount() {
        if (!stopped) {
            throw new IllegalStateException("not stopped yet.");
        }
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileTest vt = new VolatileTest();
        Thread t = new Thread(vt);
        t.start();
        Thread.sleep(1000L);
        vt.stopCounting();
        System.out.println("Count 2 = " + vt.getCount());
    }
}

推荐答案

Victor是正确的,您的代码存在问题:原子性和可见性.

Victor is right, there are issues with your code: atomicity and visibility.

这是我的版本:

    private int count;
    private volatile boolean stop;
    private volatile boolean stopped;

    @Override
    public void run() {
        while (!stop) {
            count++; // the work
        }
        stopped = true;
        System.out.println("Count 1 = " + count);
    }

    public void stopCounting() {
        stop = true;
        while(!stopped)
           ; //busy wait; ok in this example
    }

    public int getCount() {
        if (!stopped) {
            throw new IllegalStateException("not stopped yet.");
        }
        return count;
    }

}

如果某个线程观察到stopped==true,则可以保证工作已完成并且结果可见.

If a thread observes that stopped==true, it's guaranteed that the work completes and the result is visible.

从易失性写入到易失性读取(在同一变量上)之间存在先发生后关联,因此如果有两个线程

There is a happens-before relation from volatile write to volatile read (on the same variable), so if there are two threads

   thread 1              thread 2

   action A
       |
 volatile write  
                  \
                     volatile read
                          |  
                       action B

动作A在动作B之前发生; B中可以看到A中的内容.

action A happens-before action B; writes in A are visible by B.

这篇关于说明volatile:此代码是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆