-1

我对 volatile 关键字的行为表示怀疑。

public class TestClassI extends Thread {

    private volatile int i=5;
    boolean flag;
    public TestClassI( boolean flag) {
        this.i=i;
        this.flag=flag;
    }   
    public void run()
    {
        if(flag)
        {
            while(true)
            {
                System.out.println(i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        else
        {
            i=10;
        }
    }
}

在主类中使用 as

public class TestMain {

    public static volatile int i=5;
    public static void main(String args[]) throws InterruptedException
    {

        TestClassI test= new TestClassI( true);
        test.start();
        Thread.sleep(1000);

        TestClassI test2=new TestClassI( false);        
        test2.start();
    }
}

我预计该值会像 5 5 5 5 10 10 10 10。但它一直在给出 5。但是每次都应该从主存储器存储和检索 i 的易失性值的性质。请解释一下这段代码有什么问题吗?

4

4 回答 4

3

您有两个TestClassI. 他们每个人都有自己的版本i(因为它是一个实例字段)。他们完全不互相干扰。

TestMain.i程序中根本没有使用静态。没有共享状态。

于 2013-08-02T07:19:03.923 回答
0

您没有i=10在循环中设置,因此它将被设置为线程中的唯一操作,但从未打印...

于 2013-08-02T07:19:20.913 回答
0

当使用 false 标志实例化对象时,run 方法初始化i为 10,然后返回。i从不打印:

if (flag) {
    // irrelevant
}
else {
    i = 10;
}
于 2013-08-02T07:18:55.627 回答
-2

volatile在这种情况下,变量无效,因为变量是int. longdouble变量受 影响volatile,它们被加载和存储在一个不能被中断的操作中,而不是两个,每个单词一个。所以volatile变量没有影响。

产生异常输出的原因i是线程之间没有共享。如果你看,i每个线程都有一个单独的线程,尽管i主类中有一个静态的。仅供参考,i主类中的 线程没有注意到它,他们根本没有注意到它。如果您希望它工作,一个简单的修改就足够了:将i线程中的变量设为静态。不在主类中,在线程中。

于 2013-08-02T07:21:04.563 回答