public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s"
+ " has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
when i run this program i am getting the output as
Alphonse: Gaston has bowed to me! Gaston: Alphonse has bowed to me!
So can two threads access a synchronized method at the same time?
Yes, they can run simultaneously both threads. If you create 2 objects of the class as each object contains only one lock and every synchronized method requires lock.
Yes. What further explanation is necessary? You've already got the idea. If a method is unsynchronized, then another thread can call it any time, with no special protection.
Only one thread per instance can execute inside a synchronized instance method.
Multiple threads accessing shared data simultaneously may lead to a timing dependent error known as data race condition. Data races may be hidden in the code without interfering or harming the program execution until the moment when threads are scheduled in a scenario (the condition) that break the program execution.
Can two threads access a synchronized method at the same time?
It depends on what object instance the two threads are trying to lock on. Two threads cannot access the same synchronized
method on the same object instance. One will get the lock and the other will block until the first thread leaves the method.
In your example, instance methods are synchronized on the object that contains them. In this case, when you call alphonse.bow(...)
you are locking on the alphonse
object. gaston.bow(...)
locks gaston
.
There are a couple of ways that you can get multiple instances of an object to lock on the same object.
You could make the method be static
and synchronized
in which case they would lock on the class object itself. There is only one of these objects per class loader.
public static synchronized void bow(Friend bower) {
They could both lock on a defined static object. Something like:
private static final Object lockObject = new Object();
...
public void bow(Friend bower) {
synchronized (lockObject) {
....
}
}
Your output could be something like the following:
gaston
thread (may) start first and calls bow(alphonse)
gaston
object and outputs: Gaston: Alphonse has bowed to me!
alphonse.bowBack(this)
.alphonse
object and outputs: Alphonse: Gaston has bowed back to me!
alphonse.bowBack(this)
exits, unlocking the alphonse
object.gaston.bow(alphonse)
exits, unlocking the gaston
object.gaston
thread exits.alphonse
thread (may) start next and calls bow(gaston)
alphonse
object and outputs: Alphonse: Gaston has bowed to me!
gaston.bowBack(this)
.gaston
object and outputs: Gaston: Alphonse has bowed back to me!
gaston.bowBack(this)
exits, unlocking the gaston
object.alphonse.bow(gaston)
exits, unlocking the alphonse
object.This could happen in a number of different orders. The alphonse
thread could run first even though it's start()
method gets called at a later time. The only thing that the locks save you from is the calling of alphonse.bow(...)
if alphonse.bowBack(...)
is currently running. As @user988052 pointed out, because each thread locks their own object and then tries to lock the other, you can easily get a deadlock.
So can two threads access a synchronized method at the same time?
Yes and no:
Yes, if the method is called on different instances of the class.
No, two threads can't simultaneously call synchronized methods on the same instance of the class. This is the case even if the two threads call different methods (as long as the instance is the same).
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