如何调试Java中无法解释的线程中断

如何调试Java中无法解释的线程中断,java,multithreading,jenkins,hudson,interrupted-exception,Java,Multithreading,Jenkins,Hudson,Interrupted Exception,我从Jenkins那里得到了一个InterruptedException,堆栈跟踪的相关部分: java.lang.InterruptedException at java.lang.Object.wait(Native Method) at hudson.remoting.Request.call(Request.java:127) at hudson.remoting.Channel.call(Channel.java:646) at hudson.remot

我从Jenkins那里得到了一个
InterruptedException
,堆栈跟踪的相关部分:

java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at hudson.remoting.Request.call(Request.java:127)
    at hudson.remoting.Channel.call(Channel.java:646)
    at hudson.remoting.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:158)
    at $Proxy33.join(Unknown Source)
    at hudson.Launcher$RemoteLauncher$ProcImpl.join(Launcher.java:861)
这种中断是出乎意料的,到目前为止还无法解释。实际上,我无法在调试器下实现这一点,它只发生在生产使用的CI中,而且很少发生在Jenkins作业执行的1%以下。到目前为止,梳理各种日志还没有找到任何有用的原因线索。远程Jenkins节点当时似乎没有断开连接

问题:如何找出中断异常的原因,或者任何其他可能有用的原因,以及上述约束


我们也欢迎任何其他关于追踪此类异常原因的想法!也许是Jenkins/Hudson特定的东西,没有被(这里的答案没有真正的帮助)覆盖。

中断异常看起来很正常。检查Jenkins源代码,我看到它得到了处理(它们关闭catch块中的资源),然后重新运行。开箱即用我不明白他们为什么这么做(首先是等待)

在等待之前查看评论:

// I don't know exactly when this can happen, as pendingCalls are cleaned up by Channel,
// but in production I've observed that in rare occasion it can block forever, even after a channel
// is gone. So be defensive against that.
wait(30*1000);
我想说的是,有人加入了等待,以克服“罕见的永远封锁的机会”,同时引入了一个死亡,从等待中断


你最好的办法是检查詹金斯问题跟踪程序,并提交一份报告,说明你的工作失败了,因为等待时不时会被打断,它会取消远程呼叫。我认为,如果他们想花那么多时间等待,他们应该回到等待,或者继续等待,但不要失败。

不幸的是,这并没有得到很好的强调,但等待条件的最佳方式是编写这样的代码:

while(条件为真){

}


您必须注意伪中断,并对其进行编码。

在等待条件为真时,应该调用
Object::wait
。如果你被打断了&条件仍然是错误的,这是一个虚假的唤醒。返回等待模式@RKajaMohideen是的,除了这不是我的等待,所以看起来是bug报告时间。是的。如果图书馆等着什么目的。它必须预见到这种被中断的情况,并且应该处理再次等待或使方法失败,而不是将异常抛出给客户端。什么是“伪中断”?我听说过(依赖于平台的)虚假唤醒,但从未听说过虚假中断。反过来,一致意见是,在捕获中断Exception时,您至少应该再次设置中断标志(通过调用Thread.currentThread().interrupt()),并且在任何情况下都不应该按照您提议的方式吞下它。
try {
  wait(1000L);
  //do something
} 
catch (InterrruptedException e) {
}