编写一段代码,使其必定产生死锁
编写一段代码,使得这段代码必定会产生死锁使用Thread.sleep
以下是一个经典的 Java 死锁实现,通过两个线程互相持有对方需要的锁来确保必定发生死锁:
public class DeadlockDemo {
// 创建两个锁对象
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
// 线程1:先获取lock1,再尝试获取lock2
Thread thread1 = new Thread(() -> {
synchronized (lock1) {
System.out.println("线程1持有lock1,等待lock2...");
try {
Thread.sleep(10000); // 等个10秒增加死锁概率
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("线程1成功获取lock2");
}
}
});
// 线程2:先获取lock2,再尝试获取lock1
Thread thread2 = new Thread(() -> {
synchronized (lock2) {
System.out.println("线程2持有lock2,等待lock1...");
try {
Thread.sleep(10000); // 等个10秒增加死锁概率
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("线程2成功获取lock1");
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("程序正常结束(这行永远不会执行)");
}
}不使用Thread.sleep
可以使用 countDownLatch 来实现死锁,思路为:
[*]新建一个count为2的 CountDownLatch 对象 latch。
[*]thread1 持有 lock1 后,调用 latch.countDown() 将计数减一,随后调用 latch.await() 等待,直到 thread2 也持有 lock2 后调用 latch.countDownd()
[*]thread2 持有 lock2 后,调用 latch.countDown()将计数减一,随后调用 latch.await() 直到 thread1 调用 latch.countDown()
[*]thread1 想要 lock2,但 thread2 持有了它
[*]thread2 想要 lock1,但 thread1 持有了它
[*]由于互相等待对方释放锁,因此死锁发生
import java.util.concurrent.CountDownLatch;
public class GuaranteedDeadlock {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
private static final CountDownLatch latch = new CountDownLatch(2);
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (lock1) {
System.out.println("Thread 1: Holding lock1...");
latch.countDown(); // 让 thread2 也开始执行
try {
latch.await(); // 保证两个线程同时竞争
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("Thread 1: Acquired lock2!");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock2) {
System.out.println("Thread 2: Holding lock2...");
latch.countDown(); // 让 thread1 也开始执行
try {
latch.await(); // 保证两个线程同时竞争
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("Thread 2: Acquired lock1!");
}
}
});
thread1.start();
thread2.start();
}
}除此之外,也可以使用CycliBarrier
错误示范
public class DeadlockExample {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (lock1) {
System.out.println("Thread 1: Holding lock1...");
// 试图获取 lock2
synchronized (lock2) {
System.out.println("Thread 1: Acquired lock2!");
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock2) {
System.out.println("Thread 2: Holding lock2...");
// 试图获取 lock1(但 lock1 此时被 Thread1 持有)
synchronized (lock1) {
System.out.println("Thread 2: Acquired lock1!");
}
}
});
thread1.start();
thread2.start();
}
}上述的代码无法保证死锁,因为Java 的线程调度是由操作系统决定的,线程的执行顺序是不可预测的,thread1 可能会在 thread2 运行前快速获取 lock1 和lock2,然后释放它们,从而避免死锁
所以这段代码死锁的发生概率不是 100%。这也是为什么第一种方式要使用Thread.sleep来保证两个线程都分别获得了锁
来源:新程序网络收集,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 感谢,下载保存了 感谢分享,下载保存了,貌似很强大 这个有用。 yyds。多谢分享 谢谢分享,试用一下 新版吗?好像是停更了吧。 很好很强大我过来先占个楼 待编辑 收藏一下 不知道什么时候能用到 懂技术并乐意极积无私分享的人越来越少。珍惜 感谢分享,下载保存了,貌似很强大 感谢,下载保存了 感谢发布原创作品,程序园因你更精彩 感谢分享,学习下。 感谢分享 收藏一下 不知道什么时候能用到 东西不错很实用谢谢分享 喜欢鼓捣这些软件,现在用得少,谢谢分享! 谢谢分享,辛苦了 不错,里面软件多更新就更好了
页:
[1]
2