很久以前,我从Java参考书中保存了一句话:"Java没有处理死锁的机制.它甚至不知道发生了死锁." (Head First Java 2nd Edition,p.516)
那么,它是什么呢?有没有办法在Java中捕获死锁案例?我的意思是,有没有一种方法可以让我们的代码了解发生死锁的情况?
从技术上讲,Java中的线程是否可以自行解锁?
我在一段时间的采访中被问到这个问题并回答说这是不可能的,但面试官告诉我这是.不幸的是,我无法获得如何实现这种僵局的方法.
这让我思考,我能想到的唯一情况就是你可以实现这一点的地方就是你有一个RMI服务器进程,其中包含一个调用自身的方法.调用该方法的代码行放在synchronized块中.
这甚至可能还是面试官不正确?
我正在考虑的源代码是这些行(其中testDeadlock在RMI服务器进程中运行)
public boolean testDeadlock () throws RemoteException {
synchronized (this) {
//Call testDeadlock via RMI loopback
}
}
Run Code Online (Sandbox Code Playgroud) 可能重复:
C#中的重入锁定
如果我写这样的代码:
class Program {
static void Main(string[] args) {
Foo();
Console.ReadLine();
}
static void Foo() {
lock(_lock) {
Console.WriteLine("Foo");
Bar();
}
}
static void Bar() {
lock(_lock) {
Console.WriteLine("Bar");
}
}
private static readonly object _lock = new object();
}
Run Code Online (Sandbox Code Playgroud)
我得到输出:
Foo
Bar
Run Code Online (Sandbox Code Playgroud)
我预计这会陷入僵局,因为Foo获得了一个锁,然后等待Bar获得锁.但这不会发生.
锁定机制是否只允许这个,因为代码是在同一个线程上执行的?
可能在我构建解决方案的25%到50%之间,我看到了这一点:
" 您请求的操作花费的时间比预期的要长.完成操作后,此对话框将关闭. "
我以我无法描述的方式讨厌这个窗口.它永远不会解决,取消按钮永远不会启用,唯一的解决方法是杀死devenv进程并再次加载我的整个解决方案,完全知道我没有修复任何东西,我同样有责任看到当我尝试构建时也一样.
我的解决方案总共约有60个项目,主要是C#类库,每个项目都包含Web应用程序,Web服务和控制台应用程序.但是,即使在卸载了大部分(50个)项目的情况下构建一个代码库时,问题仍然存在.
我的问题是输出窗口没有告诉我它冻结的任何地方,我不知道如何确定这种锁定的原因.如果我猜测,我会认为这是文件系统中的死锁或其他什么,但我不知道如何证明这一点 - 更不用说如何防止它.
我可以做些什么来诊断并消除我的解决方案,以便我再也看不到它?一般来说,如何诊断构建期间出现的问题?
为什么这段代码不会造成死锁?
private static readonly object a = new object();
Run Code Online (Sandbox Code Playgroud)
...
lock(a)
{
lock(a)
{
....
}
}
Run Code Online (Sandbox Code Playgroud) 我正在研究java线程和死锁,我理解死锁的例子,但我想知道是否有一般规则要遵循以防止它.
我的问题是,是否有规则或技巧可以应用于java中的源代码以防止死锁?如果是,您能解释一下如何实施吗?
考虑以下代码:
public synchronized void onSignalsTimeout(List<SignalSpec> specs) {
if (specs != null && specs.size() > 0) {
for (SignalSpec spec : specs) {
ParsedCANSignal timeoutedSignal = new ParsedCANSignal();
SignalsProvider.getInstance().setSignal(spec.name, spec.parent.parent.channel, timeoutedSignal);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个简单的问题:当线程1调用onSignalsTimeout方法时,线程2可以访问在该方法中访问的对象吗?
如果'synchronized'锁只能访问此方法或访问此方法中使用的所有对象,则无法找到任何位置.