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