Reputation: 273
Here's some simple example of a method that doesn't use synchronization and causes data race and its "improved" version without this problem
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();
}
}
It prints something like this:
1 2 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
First 9 digits - data race, next 9 digits - no data race, almost as expected, but what about this line before initializing and starting threads with synchronized methods?
Counter.count = 0;
Why didn't it work?
Upvotes: 0
Views: 1899
Reputation: 533730
You didn't wait for the first threads to finish before resetting the counter, and as the threads take time to start, it is highly likely that the count = 0;
occurs long before any thread starts.
Upvotes: 5
Reputation: 50094
It doesn't work because the previously started three threads are still running and increment the variable. You should join the threads to wait for their completion, before continuing with the second test case.
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
Upvotes: 3