线程是否有可能使死锁本身?

2022-08-31 15:52:08

从技术上讲,Java中的线程是否有可能使自身死锁?

不久前,我在一次面试中被问到这个问题,并回答说这是不可能的,但面试官告诉我,这是不可能的。不幸的是,我无法得到他关于如何实现这个僵局的方法。

这让我开始思考,我能想到的唯一情况是,你可以在哪里发生这种情况,你有一个RMI服务器进程,其中包含一个调用自己的方法。调用该方法的代码行放置在同步块中。

这甚至可能,还是面试官不正确?

我正在考虑的源代码是沿着这些路线(testDeadlock在RMI服务器进程中运行)

public boolean testDeadlock () throws RemoteException {
    synchronized (this) {
        //Call testDeadlock via RMI loopback            
    }
}

答案 1

好吧,基于以下定义:

死锁是指两个或多个相互竞争的操作各自等待另一个操作完成的情况。

我会说答案是否定的 - 当然,线程可以无限期地坐在那里等待某些东西,但是除非个相互竞争的操作正在等待彼此,否则根据定义,它不是死锁。

除非有人向我解释单个线程如何同时等待两个操作完成?

更新:我能想到的唯一可能的情况是某种消息泵,其中线程处理一条消息,该消息要求它无限期地等待某些事情发生,实际上,该消息将由消息泵上的另一条消息处理。

这种(令人难以置信的人为的)情况在技术上可能被称为死锁。


答案 2

这取决于你所说的“死锁”到底是什么意思。例如,您可以轻松地在显示器上,而显示器上没有任何脉冲...但我不认为我会这样说是死锁。wait()

沿着“调用自身的方法”进行思考,如果您的服务器只运行一定数量的线程,那么它们都可能忙于等待来自同一服务器的响应(如果这算数的话)。(最简单的示例:服务器仅使用一个线程进行处理。如果您编写一个调用同一服务器的请求处理程序,它将等待被阻止的线程完成对请求的处理,然后才能为相同的请求提供服务...)这并不是一个真正的“同步块”类型的死锁,但它肯定是一个危险需要注意。

编辑:要将此答案应用于其他定义,此处的竞争操作将是“完成当前请求”和“处理新请求”。每个操作都在等待另一个操作发生。