编写一个肯定会陷入死锁的程序 [已关闭]
2022-08-31 11:42:53
我最近在一次采访中问了这个问题。
我回答说,如果交错出错,就会发生死锁,但是面试官坚持认为,可以编写一个无论交错如何都会始终陷入死锁的程序 。
我们可以写这样的程序吗?你能给我指出一些这样的示例程序吗?
我最近在一次采访中问了这个问题。
我回答说,如果交错出错,就会发生死锁,但是面试官坚持认为,可以编写一个无论交错如何都会始终陷入死锁的程序 。
我们可以写这样的程序吗?你能给我指出一些这样的示例程序吗?
更新:这个问题是我在2013年1月博客的主题。谢谢你的好问题!
我们如何编写一个无论线程如何调度都始终陷入死锁的程序?
下面是 C# 中的一个示例。请注意,该程序似乎不包含任何锁和共享数据。它只有一个局部变量和三个语句,但它以100%的确定性死锁。人们很难想出一个更简单的程序来确保僵局。
向读者练习#1:解释这种死锁是如何发生的。(评论中有答案。
给读者练习#2:在Java中演示相同的死锁。(答案在这里:https://stackoverflow.com/a/9286697/88656)
class MyClass
{
static MyClass()
{
// Let's run the initialization on another thread!
var thread = new System.Threading.Thread(Initialize);
thread.Start();
thread.Join();
}
static void Initialize()
{ /* TODO: Add initialization code */ }
static void Main()
{ }
}
此处的闩锁确保在每个线程尝试锁定另一个线程时保持两个锁:
import java.util.concurrent.CountDownLatch;
public class Locker extends Thread {
private final CountDownLatch latch;
private final Object obj1;
private final Object obj2;
Locker(Object obj1, Object obj2, CountDownLatch latch) {
this.obj1 = obj1;
this.obj2 = obj2;
this.latch = latch;
}
@Override
public void run() {
synchronized (obj1) {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException();
}
synchronized (obj2) {
System.out.println("Thread finished");
}
}
}
public static void main(String[] args) {
final Object obj1 = new Object();
final Object obj2 = new Object();
final CountDownLatch latch = new CountDownLatch(2);
new Locker(obj1, obj2, latch).start();
new Locker(obj2, obj1, latch).start();
}
}
运行jconsole很有趣,它将正确显示“线程”选项卡中的死锁。