使用计数器的 Java 数据竞争示例

标签 java multithreading race-condition

下面是一些不使用同步并导致数据争用的方法的简单示例,以及没有此问题的“改进”版本

class Counter {
    public static long count = 0;
}

class UseCounter implements Runnable {    
    public static void increment() {
        Counter.count++;
        System.out.print(Counter.count + " ");
    }    
    public void run() {
        increment();
        increment();
        increment();
    }    
}

class SynchronizedUseCounter implements Runnable {    
    public static synchronized void increment() {
        Counter.count++;
        System.out.print(Counter.count + " ");
    }    
    public void run() {
        increment();
        increment();
        increment();
    }
}

public class DataRaces {
    public static void main(String[] args) {
        UseCounter c = new UseCounter();
        Thread t1 = new Thread(c);
        Thread t2 = new Thread(c);
        Thread t3 = new Thread(c);
        t1.start();
        t2.start();
        t3.start();

        Counter.count = 0;

        SynchronizedUseCounter sc = new SynchronizedUseCounter();
        Thread t4 = new Thread(sc);
        Thread t5 = new Thread(sc);
        Thread t6 = new Thread(sc);
        t4.start();
        t5.start();
        t6.start();
    }
}

它打印出这样的内容:

1 2 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

前 9 位数字 - 数据争用,接下来的 9 位数字 - 无数据争用,几乎与预期一致,但是在使用同步方法初始化和启动线程之前,这一行怎么样?

Counter.count = 0;

为什么没有成功?

最佳答案

在重置计数器之前,您没有等待第一个线程完成,并且由于线程需要时间来启动,因此 count = 0; 很可能早于任何线程发生开始。

关于使用计数器的 Java 数据竞争示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24418805/

相关文章:

php - PDO、多语句和竞争条件

mysql - 这是否足够,或者我是否有竞争条件?

ruby-on-rails - 如何进行 Ruby on Rails 并发测试?

java - POI 的 HSSF 数据格式 - 支持哪些颜色?

python - 为什么gevent会执行这个未连接的greenlet?

.net - 可能的线程,变量复制问题

ios - 在后台 Context 上保存 NSManagedObject 时出现问题

java - MySQL 5.6.22 使用 Java-5.0.8 连接器触发 SocketException

java - 创建一个包含对象集合信息的 map

java - 有没有办法将 String.format 传递给 thymeleaf 模板?