我使用的是java 1.8 java.util.concurrent.LinkedBlockingQueue
,当我打电话时:
LinkedBlockingQueue.poll(5000, TimeUnit.MILLISECONDS)
偶尔会抛出InterruptedException
:
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2088)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
我认为正在发生这种情况,因为以下内容在checkInterruptWhileWaiting() at AbstractQueuedSynchronizer:2079
Unsafe.compareAndSwapInt(...)
作为旁注,Unsafe.compareAndSwapInt
会返回boolean
,但boolean
是什么意思?我无法找到关于该类/功能的任何文档。
我怀疑另一个线程中发生的事情导致了这个问题,但我不知道现在该去哪里看。
任何帮助理解InterruptedException
被抛出的原因都会非常有帮助。我真的希望能够在一个小的测试程序中重现它,但它现在处于一个大乱的程序中,所以我试图理解可能导致这种情况的因素,以便我可以创建一个测试程序来重现它。
答案 0 :(得分:0)
您的应用中是否有其他线程调用Thread.interrupt()
?这就是awaitInNanos()
:
if (Thread.interrupted())
throw new InterruptedException();
如果你控制线程,那么你可以覆盖interrupt
方法仅用于测试:
Thread thread = new Thread() {
@Override
public void run() {
// do something longrunning
}
@Override
public void interrupt() {
// try-finally ensures to run both super.interrupt() and the deubg code
try {
super.interrupt();
} finally {
// you can use any logging services that you already have
System.out.println("--> Interrupted from thread: " + Thread.currentThread().getName());
Thread.dumpStack();
}
}
};
如果手动创建线程,则可以覆盖interrupt()
。如果您使用执行程序,那么您可以提供ThreadFactory
,使用正确的interrupt()
方法创建线程。
这是一个使用此调试技术的main()
方法。请注意,您需要在STDIN
中输入一行或手动终止该过程。否则它将永远运行(jvm restart)。
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
System.out.println("--> asdf");
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
br.readLine();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
@Override
public void interrupt() {
// try-finally ensures to run both super.interrupt() and the deubg code
try {
super.interrupt();
} finally {
// you can use any logging services that you already have
System.out.println("--> Interrupted from thread: " + Thread.currentThread().getName());
Thread.dumpStack();
}
}
};
thread.start();
System.out.println("--> before interrupt");
thread.interrupt();
System.out.println("--> after interrupt");
}