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

时间:2014-06-25 21:21:38

标签: 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;

为什么它不起作用?

2 个答案:

答案 0 :(得分:5)

你没有等到第一个线程在重置计数器之前完成,并且由于线程需要时间来启动,很可能在任何线程启动之前很久就会发生count = 0;

答案 1 :(得分:3)

它不起作用,因为先前启动的三个线程仍在运行并增加变量。在继续第二个测试用例之前,您应该加入线程以等待它们完成。

t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();