繁体   English   中英

在原子变量上使用volatile

[英]using volatile on atomic variables

在变量上使用volatile可以降低内存一致性错误的风险(如果这揭示了我对任何相关概念的理解中的一些漏洞,请纠正我)。 因此,在下面的示例中,即使变量c1是易失性的,仍然发生内存持续性错误导致c1在输出中变为15或有时为14而不是正确的输出16。

class Lunch implements Runnable {

    private volatile long c1 = 0;
    private Object lock1 = new Object();
    private Object lock2 = new Object();
    public void inc1() {
       // synchronized(lock1) { c1 is volatile
            c1++;
       // }
    }

    public void run() {
        try {
            inc1();
            Thread.sleep(1000);
            inc1();
            Thread.sleep(1000);
            inc1();
            Thread.sleep(1000);
            inc1();
            inc1();
            Thread.sleep(1000);
            inc1();
            Thread.sleep(1000);
            inc1();
            Thread.sleep(1000);
            inc1();
        }
        catch(InterruptedException e) {
            return;
        }
    }
    public long value() {
        return c1;
    }
    public static void main(String args[]) throws InterruptedException {
        Lunch l = new Lunch();
       Thread t1 = new Thread(l);
       Thread t2 = new Thread(l);
       t1.start();
       t2.start();
       t1.join();
       t2.join();
       System.out.println(l.value());
    }
} 

你是对的。 因为++不是原子操作,所以当线程读取/递增/写入另一个线程的值时,您仍然可以获得不一致的结果。

考虑使用AtomicInteger这样的情况。

原子性只是图片的一部分。 还有可见性 如果更改了非易失性(和非同步)变量值,则无法保证其他线程能够及时查看更改。

查看http://www.javabeat.net/tips/169-volatile-keyword-in-java.html以了解volatile的作用。 它避免了中间线程缓存,但无论如何,可能存在从读取其值并在非原子操作中更新的损失更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM