har*_*ish 12 java multithreading
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();
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个程序时,我得到输出为
阿方斯:加斯顿向我鞠躬致敬!加斯顿:阿尔方斯向我鞠躬致敬!
那么两个线程可以同时访问同步方法吗?
Gra*_*ray 13
两个线程可以同时访问同步方法吗?
实例方法(如您的示例)在包含它们的对象上同步.在这种情况下,当您调用时,synchronized您将锁定该alphonse.bow(...)对象.alphonse锁gaston.bow(...).
有几种方法可以让对象的多个实例锁定在同一个对象上.
你可以使方法成为gaston,static在这种情况下,他们将锁定类对象本身.每个类加载器只有一个这样的对象.
public static synchronized void bow(Friend bower) {
Run Code Online (Sandbox Code Playgroud)它们都可以锁定定义的静态对象.就像是:
private static final Object lockObject = new Object();
...
public void bow(Friend bower) {
synchronized (lockObject) {
....
}
}
Run Code Online (Sandbox Code Playgroud)您的输出可能如下所示:
synchronized线程(可能)开始第一和电话gastonbow(alphonse)对象和输出:gastonGaston: Alphonse has bowed to me!.alphonse.bowBack(this)对象和输出:alphonseAlphonse: Gaston has bowed back to me!退出,解锁alphonse.bowBack(this)对象.alphonse退出,解锁gaston.bow(alphonse)对象.gaston线程退出.gaston线程(可能)明年开始,并呼吁alphonsebow(gaston)对象和输出:alphonseAlphonse: Gaston has bowed to me!.gaston.bowBack(this)对象和输出:gastonGaston: Alphonse has bowed back to me!退出,解锁gaston.bowBack(this)对象.gaston退出,解锁alphonse.bow(gaston)对象.这可能发生在许多不同的订单中.该alphonse线程可以先运行,即使它的alphonse方法被调用在以后的时间.锁定保存的唯一内容是调用start()if alphonse.bow(...)当前正在运行.正如@ user988052指出的那样,因为每个线程锁定自己的对象,然后尝试锁定另一个,所以很容易出现死锁.
NPE*_*NPE 10
那么两个线程可以同时访问同步方法吗?
是和否:
是的,如果在类的不同实例上调用该方法.
不,两个线程不能同时在类的同一个实例上调用synchronized方法.即使两个线程调用不同的方法(只要实例是相同的),情况也是如此.