Krishna Chaitanya
Krishna Chaitanya

Reputation: 2663

Synchronization: What is wrong in my code?

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

Answers (2)

Alexei Kaigorodov
Alexei Kaigorodov

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

Aleksey Shipilev
Aleksey Shipilev

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:

  1. main calls dec(), grabs the lock, decrements, exits, releases the lock;
  2. other calls inc(); grabs the lock, increments, exits, releases the lock;
  3. main calls print(); grabs the lock, reads 0, exits, releases the lock;
  4. other calls print(), grabs the lock, reads 0, exits, releases the lock.

Upvotes: 4

Related Questions