Oha*_*had 22 java multithreading deadlock synchronized
谁能解释一下:
bowBack()以退出函数bow()- 或)?这是我得到的输出 - 然后程序卡住了!
阿方斯:加斯顿向我鞠躬致敬!
加斯顿:阿尔方斯向我鞠躬致敬!
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)
Usa*_*oto 23
的synchronized块/方法被同步到this,即该对象实例的块/方法被调用.(对于static"对象实例",将替换为"类实例".)
那就是你的2个对象与自己同步,而不是常见的对象.
尝试这样的事情:
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void bow(Friend bower) {
synchronized (getClass()) {
System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
}
public void bowBack(Friend bower) {
synchronized (getClass()) {
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)
线程1:
alphonse实例被锁定,alphonse.bow(gaston);从中打印出一行然后调用gaston.bowBack()(但是gaston由于bow()下面调用的同步实例而被线程2锁定)
线程2:
gaston实例被锁定,gaston.bow(alphonse);从中打印一行,然后调用alphonse.bowBack()(但alphonse由于bow()调用了同步实例,因此从线程1锁定)
所以他们都在等待释放并且无法退出bow()方法,因此死锁
您的示例中会发生什么:
线程Alphonse通过输入函数获取对Alphonse的锁定bow.
线程加斯顿通过输入功能获取对加斯顿的锁定bow.
线程Alphonse请求锁定Gaston进入该功能,bowBack但该锁定目前由Thread Gaston持有,因此Alphonse被迫等待.
线程Gaston请求锁定Alphonse进入该功能,bowBack但该锁定目前由Thread Alphonse持有,因此Gaston被迫等待.
僵局.
为什么会这样:
一个synchronized功能是语法糖synchronized(this) { ... }所以上面的类也可以写成这样:
public void bow(Friend bower) {
synchronized (this) {
System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
}
public void bowBack(Friend bower) {
synchronized (this) {
System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
this但是在这个例子中是类的实例,所以每个实例都有它的单独锁.如果要在类的所有实例中锁定同一对象,则需要锁定如下的静态对象:
protected static final Object STATIC_LOCK = new Object();
public void bow(Friend bower) {
synchronized (STATIC_LOCK) {
System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
}
public void bowBack(Friend bower) {
synchronized (STATIC_LOCK) {
System.out.format("%s: %s has bowed back to me!%n", this.name, bower.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
由于此LOCK对象是静态的,因此两个线程现在将锁定在同一个对象上,因此可以正确地相互锁定.请注意final在这种情况下强烈建议的关键字,因为否则在执行期间(通过代码中的错误或疏忽)可能会更改同步锁定,这会使您回到死锁状态,原因与上述完全相同.
| 归档时间: |
|
| 查看次数: |
3455 次 |
| 最近记录: |