Reputation: 10551
The printed result is -20000000
, which proves that I don't need to synchronize the size()
method. But my understanding is that I should synchronize size()
too. What's the real situation here?
public class Test {
public static void main(String[] args){
Counter c = new Counter();
T1 t1 = new T1(c);
T1 t2 = new T1(c);
t1.start();
t2.start();
try{
t1.join();
t2.join();
} catch (Throwable t) {
}
System.out.println("c=" + c.size());
}
}
class T1 extends Thread{
private Counter c;
public T1(Counter c){
this.c = c;
}
public void run(){
for(int i=0; i<10000000; i++){
c.decrement();
}
}
}
class Counter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public int size() {
return c;
}
}
Upvotes: 0
Views: 97
Reputation: 128879
proves that I don't need to synchronize the size() method
Actually, it only proves that your counter can work sometimes. size()
should be synchronized because, basically, the field it accesses could be cached in multiple registers simultaneously, and without any kind of indication that the field is shared among threads, several threads could be working on purely local copies of the same field without ever syncing back to main memory.
The fact that you don't see any problems when you run it is only proof that writing concurrent code in this style is a bad idea.
Upvotes: 0
Reputation: 19682
It does work in your example, because after t1.join()
and t2.join()
, any changes made in t1 and t2 are visible to the main thread.
quoting http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.4
The final action in a thread T1 synchronizes-with any action in another thread T2 that detects that T1 has terminated.
T2 may accomplish this by calling T1.isAlive() or T1.join().
Basically, when a thread starts, it should see all prior changes; after a thread finishes, what it has changed should be visible to others. If thread A starts B, and thread C joins thread B
A B C
|
w1
|
start B --> o
. |
. |
. r1 .
w2 .
| .
| |
o --> join B
|
r2
It's guaranteed that r1 sees w1, r2 sees w2.
Upvotes: 1