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();
}
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.
So can two threads access a synchronized method at the same time? Yes, if the method is called on different instances of the class.
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.
Only one thread per instance can execute inside a synchronized instance method.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With