使用计数器的Java数据竞争示例
下面是一个不使用同步的方法的简单示例,它会导致数据竞争,并且改进后的版本不会出现此问题使用计数器的Java数据竞争示例,java,multithreading,race-condition,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 + " ");
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();
}
}
它打印出如下内容:
123123456789101113141414 15
前9位-数据竞争,后9位-没有数据竞争,几乎和预期的一样,但是在初始化和启动同步方法的线程之前,这一行怎么样
Counter.count = 0;
为什么它不工作?它不工作,因为之前启动的三个线程仍在运行,并递增变量。在继续第二个测试用例之前,您应该加入线程以等待它们的完成
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
在重置计数器之前,您没有等待第一个线程完成,并且由于线程需要时间启动,因此计数很可能为0;在任何线程启动之前很久发生