Reputation: 2663
I am reading about synchronization here. Then I wrote this program
public class Counter {
int i = 0;
public synchronized void increment() {
System.out.println("inc called");
i++;
System.out.println("inc exited");
}
public synchronized void decrement() {
System.out.println("dec called");
i--;
System.out.println("dec exited");
}
public synchronized void print(String name) {
System.out.println(name + " " + i);
}
}
public class UnsynchronizedCounterTest implements Runnable {
private Counter counter = new Counter();
public UnsynchronizedCounterTest(String name) {
Thread t = new Thread(this, name);
t.start();
}
public static void main(String[] args) {
UnsynchronizedCounterTest test = new UnsynchronizedCounterTest(
"New Thread 1");
test.callMe();
}
public void callMe() {
counter.decrement();
counter.print("main thread");
}
@Override
public void run() {
counter.increment();
counter.print("another thread");
}
}
When I run this program I get below outputs
dec called
dec exited
inc called
inc exited
another thread 0
main thread 0
dec called
dec exited
main thread -1
inc called
inc exited
another thread 0
I believe that the first output is wrong. I dont know what is wrong in my program. Can anyone please correct me.
Upvotes: 0
Views: 109
Reputation: 13535
Following code:
counter.decrement();
counter.print("main thread");
is dangerous. While it in 99% prints the correct value of Counter.i
, sometimes another thread can wedge in the gap between the first and second method calls. Better print the value inside decrement and increment methods. If you want just to print without changing the value, just the same use synchronized method or block, to avoid printing stale value.
The outputs correspond to your program - if you think they are wrong, you program is wrong also. Please explain what you want.
Upvotes: 3
Reputation: 18857
The first output is correct, because the locks are granular to method calls.
Your output describes the plausible execution which justifies your output:
main
calls dec()
, grabs the lock, decrements, exits, releases the lock;other
calls inc()
; grabs the lock, increments, exits, releases the lock;main
calls print()
; grabs the lock, reads 0, exits, releases the lock;other
calls print()
, grabs the lock, reads 0, exits, releases the lock.Upvotes: 4