13

consider the following code:

public class SynchronizedCounter extends Thread {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public void run() {
        for(;;)
            increment();
    }
}

static void main(String[] args) {
    SynchronizedCounter counter = new SynchronizedCounter();
    counter.start();
    for(;;)
        counter.decrement();
}

does this means that increment() and decrement() methods will wait for each other to finish or not?

EDIT: and this does not wait?

static void main(String[] args) {
    SynchronizedCounter counter1 = new SynchronizedCounter();
    SynchronizedCounter counter2 = new SynchronizedCounter();
    counter1.start();
    for(;;)
        counter2.decrement();
}
MBZ
  • 26,084
  • 47
  • 114
  • 191

3 Answers3

13

Yes, the synchronized keyword is a shorthand for:

synchronized(this) {
  //...
}

So both methods are effectively locking on the same mutex object. If you want them to be independent from each other (which is a bad idea in this example as they both access the same value), see Object locking private class members - best practice? (Java).

BTW your SynchronizedCounter should implement Runnable rather than extending a Thread since you are passing it to other thread's constructor - now it is a bit confusing.

Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
6

The lock is always on the entire object. If any of it's the synchronized members are accessed.

In your first example, there are two threads contending for the same counter object, the one you started explicitly (which calls the increment() method in infinite loop) and the other thread is the main thread (which calls the decrement() infinitely).

In the second example, there are two objects created counter1 and counter2. These will have their own locks independent of each other. Locking of one object does not affect the other threads from accessing other object. The two threads (the explicit and the main thread) acquire lock on two different objects and hence there in no contention.

Santosh
  • 17,667
  • 4
  • 54
  • 79
2

does this means that increment() and decrement() methods will wait for each other to finish or not?

NO, it means that no other thread will be able to call increment() and decrement() when one thread is within them. To be complete, other thread could not execute any synchronized method of this instance/object

You could call any other synchronized method from a synchronized one without lock on the same instance/object

stefan bachert
  • 9,413
  • 4
  • 33
  • 40