java - 在原子变量上使用 volatile

标签 java multithreading concurrency volatile

在变量上使用 volatile 可以降低内存一致性错误的风险(如果这揭示了我对任何相关概念的理解存在一些漏洞,请纠正我)。因此在下面的示例中,即使变量 c1 是 volatile 的,内存恒常性错误的发生仍然会导致输出中的 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。

关于java - 在原子变量上使用 volatile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3636188/

相关文章:

java - 多线程 - 在线程池中安排永无休止的可运行

java - 非线程安全数据的 AtomicBoolean 保护( volatile 搭载)

ios - 异步调度队列中只有两个任务并发运行

groovy - 在 Groovy 中如何同时执行两个任务并等待结果?

java - 如何从 spring boot pom 中排除或替换 jackson

java - 在 MVC WAR 和 Batch Jar 之间共享 Spring 应用程序上下文

java - 如何调试服务器

多线程 - 一组中所有对之间的计算

java - 将方法与返回的 jcomponents 和泛型一起使用

android - Android 中的 EditText 值