java - Java 官方死锁示例
问题描述
我从Oracle官方网站阅读了教程并看到了这个例子
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) throws Exception{
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();
}
}
我不明白为什么会发生死锁?据我了解,线程 alphonse 执行完成然后释放锁,然后线程 gaston 将继续执行,没有死锁。
解决方案
你应该运行它看看。它永远不会退出。
当你得到一个线程转储时,你会看到两个线程:
"Thread-0" #14 prio=5 os_prio=31 cpu=16.42ms elapsed=8.92s tid=0x00007fb3e6000000 nid=0x6603 waiting for monitor entry [0x0000700004ef3000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlock$Friend.bowBack(Deadlock.java:17)
- waiting to lock <0x000000061fff4b78> (a Deadlock$Friend)
at Deadlock$Friend.bow(Deadlock.java:14)
- locked <0x000000061fff4b38> (a Deadlock$Friend)
at Deadlock$1.run(Deadlock.java:29)
at java.lang.Thread.run(java.base@15-ea/Thread.java:832)
和
"Thread-1" #15 prio=5 os_prio=31 cpu=0.71ms elapsed=8.92s tid=0x00007fb3e587ee00 nid=0x8e03 waiting for monitor entry [0x0000700004ff6000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Deadlock$Friend.bowBack(Deadlock.java:17)
- waiting to lock <0x000000061fff4b38> (a Deadlock$Friend)
at Deadlock$Friend.bow(Deadlock.java:14)
- locked <0x000000061fff4b78> (a Deadlock$Friend)
at Deadlock$2.run(Deadlock.java:35)
at java.lang.Thread.run(java.base@15-ea/Thread.java:832)
查看每个已锁定并正在等待的监视器的 ID。
您可以看到第一个线程正在等待第二个线程持有的锁,反之亦然。
推荐阅读
- ruby-on-rails - 重新启动heroku服务器后在某些端点上出现503错误(Ruby on Rails)
- python - 正则表达式检查有多少字符被空白字符包围
- python - 按钮点击功能与postgresql连接
- javascript - 试图从 Pinterest “嵌入 pin” 中删除标题和个人资料
- google-apps-script - 使用参数范围调用脚本函数
- sockets - 通过 VPN 发送欺骗的 UDP 数据包
- typescript - 接口的重载方法不能接受联合类型:“没有重载匹配此调用”
- browser - 本地浏览器到浏览器与 Web RTC 的通信
- google-analytics - Google Analytics / Data Studio - 在处理数据之前从 URL 中间删除字符串
- python - 在python中生成xml文件时,输出中没有空格