Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java two synchronized methods in one instance

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();
}
like image 797
MBZ Avatar asked May 13 '12 11:05

MBZ


People also ask

Can two synchronized methods run at the same time?

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

Can two threads access two different synchronized methods of a single class at the same time?

So can two threads access a synchronized method at the same time? Yes, if the method is called on different instances of the class.

What will happen if a synchronized method is called by two threads?

If another thread tries to access any method declared with the synchronized keyword of the same object, it will be suspended until the first thread finishes the execution of the method.

How many trades for instance can execute inside a Synchronised instance method?

Only one thread per instance can execute inside a synchronized instance method.


2 Answers

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.

like image 100
Tomasz Nurkiewicz Avatar answered Oct 02 '22 16:10

Tomasz Nurkiewicz


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.

like image 31
Santosh Avatar answered Oct 02 '22 17:10

Santosh