java - 用一个简单的例子理解死锁
问题描述
我正在努力理解死锁的基础知识,所以我想出了下面的代码。我有两个线程以相反的顺序获取锁,但它们没有死锁。当我运行它时,我会看到所有的打印输出。我究竟做错了什么?
public class DeadlockBasics {
private Lock lockA = new ReentrantLock();
private Lock lockB = new ReentrantLock();
public static void main(String[] args) {
DeadlockBasics dk = new DeadlockBasics();
dk.execute();
}
private void execute() {
new Thread(this::processThis).start();
new Thread(this::processThat).start();
}
// called by thread 1
public void processThis() {
lockA.lock();
// process resource A
System.out.println("resource A -Thread1");
lockB.lock();
// process resource B
System.out.println("resource B -Thread1");
lockA.unlock();
lockB.unlock();
}
// called by thread 2
public void processThat() {
lockB.lock();
// process resource B
System.out.println("resource B -Thread2");
lockA.lock();
// process resource A
System.out.println("resource A -Thread2");
lockA.unlock();
lockB.unlock();
}
}
解决方案
首先,没有保证哪个线程首先启动。要获得死锁,一个线程必须锁定lockA
,然后第二个线程必须锁定,lockB
反之亦然。
public void processThis() {
lockA.lock();
// here the control should be switched to another thread
System.out.println("resource A -Thread1");
lockB.lock();
...
但是可能没有足够的时间在线程之间切换,因为您只有几行代码。它太快了。为了模拟一些长时间的工作,在两种方法的第二个锁定之前添加延迟
lockA.lock();
Thread.sleep(200); // 200 milis
然后第二个线程将能够lockB
在第一个释放之前锁定它们
推荐阅读
- unity3d - 将相机夹在多边形对撞机的范围内?
- php - 如何在 WooCommerce 订单项中获取 ACF 产品字段值
- excel - 如果范围包含合并单元格,则第一个单元格的查找方法失败
- r - 如何删除前导和结束分号和空格
- google-oauth - 仅对 Google Drive 使用 Blazor OIDC 身份验证和 Google OAuth
- list - 如何在列表中选定的单个按钮上加边框
- time-series - 在 AWS Timestream 中重放事件并摄取它们
- python - 模型输出没有去量化。张量流 2.4.1
- javascript - Chartjs:双x轴没有相同的网格线
- python - 如何重新索引两个熊猫数据框中的列,以使它们都具有相同的列?