Reputation: 109
I'm learning concurrency basics in Java and I'm stuck with one problem in this example below. There are two threads that should run concurrently and finish their loops working on some global static object. I expected that one thread could finish before another and print different value but I didn't expect to see both of threads printing the same value which suggest that both of them did not finish their loops before printing output.
Code:
public class TestThreads {
public static void main(String[] args) {
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}
class Accum {
private static Accum a = new Accum();
private int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public int getCount() {
return counter;
}
public void updateCounter(int add) {
counter += add;
}
}
class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x < 98; x++) {
a.updateCounter(1000);
try {
Thread.sleep(50);
} catch(InterruptedException ex) { }
//System.out.println("index in one = " + x);
}
System.out.println("one " + a.getCount());
}
}
class ThreadTwo implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x < 99; x++) {
a.updateCounter(1);
try {
Thread.sleep(50);
} catch(InterruptedException ex) { }
//System.out.println("index in two = " + x);
}
System.out.println("two " + a.getCount());
}
}
Why is this happening? When I tried to debug with print statements (commented in code above) everything starts to work as expected.
My output: (it's different each time, this is also strange)
one 82067 two 82067
This is actually a code-puzzle from book "Head First Java" (2nd Edition), but author provides the same code as above as solution to different behavior.
Book output: (the same code as above)
one 98098 two 98099
Book explanation:
Threads from two different classes are updating the same object in a third class, because both threads are accessing a single instance of Accum.
To sum up, my questions are:
** - Additional
Upvotes: 0
Views: 207
Reputation: 53694
no idea how the book expects that to work, but your Accum instance is not thread safe. therefore, each time you run it you could get a different answer. If you make updateCounter() and getCount() synchronized, it should work reliably.
Upvotes: 2