这是一个简单的方法示例,该方法没有使用同步并导致数据竞争及其改进"没有这个问题的版本
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;
为什么它不起作用?
答案 0 :(得分:5)
你没有等到第一个线程在重置计数器之前完成,并且由于线程需要时间来启动,很可能在任何线程启动之前很久就会发生count = 0;
。
答案 1 :(得分:3)
它不起作用,因为先前启动的三个线程仍在运行并增加变量。在继续第二个测试用例之前,您应该加入线程以等待它们完成。
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();