Infinite loop in EventQueue.isDispatchThread()

我有一个Java程序占用100%的CPU,但似乎什么都不做。

如果我采用线程转储,则有 4 个线程(在 5 个线程池中)等待获取锁。

"Incoming WorkPool 5" - Thread t@363
   java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - waiting to lock <7212149b> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) owned by "Incoming WorkPool 3" t@354
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
    at java.awt.EventQueue.isDispatchThreadImpl(EventQueue.java:1019)
    at java.awt.EventQueue.isDispatchThread(EventQueue.java:1014)

他们正在等待的线程是RUNNABLE的

"Incoming WorkPool 3" - Thread t@354
   java.lang.Thread.State: RUNNABLE
    at java.awt.EventQueue.isDispatchThreadImpl(EventQueue.java:1024)
    at java.awt.EventQueue.isDispatchThread(EventQueue.java:1014)

这是JDK 7.0.25,所以似乎有一个线程卡住了

EventQueue next = eq.nextQueue;
while (next != null) {
    eq = next;
    next = eq.nextQueue;
}

有两个 AWT 事件队列线程,尝试获取相同的 pushpoplock。

VM 作为服务运行,因此它不应尝试执行 AWT 操作,但它是由我正在使用的库完成的。

有什么想法吗?我可以防止这种情况发生吗?

谢谢!


答案 1

您的应用程序是否可能调用并推送相同的事件队列?如果是,那么,它将是相同的对象,它们将在无限循环中运行,消耗CPU到100%。push(EventQueue newEventQueue)thisnextQueue

从堆栈跟踪中可以明显看出至少有一个线程正在运行。所以这不是一个死锁的问题。

从100%的CPU消耗提示及其作为RUNNABLE的状态来看,很明显它正在执行无限循环。

当且仅当 具有已在链中的值(或 )时,代码才能进入无限循环。这很可能是一个应用程序问题。谢谢。nextQueuethis


答案 2

你的问题是一个死锁问题(参见wikipeida)。

Deadlock situation here正如您在上面所看到的,您的两个事件队列(此处为 R1 和 R2)处于死锁状态 - 它们中的每一个都已声明一个资源并且无法进一步运行,而另一个已声明另一个资源。两人都在无休止地等待着对方。

您可以使用不同的方法解决此问题:

尝试更改库,你是对的,如果库不是与awt密切相关的库,则不应尝试做awt。在github这样的平台上有很多库,我很确定你找到另一个库来替换你的库,导致错误。

如果您能够编辑代码以添加监视,则还可以防止任何死锁。

synchronized(lock){
EventQueue next = eq.nextQueue;
while (next != null) {
    eq = next;
    next = eq.nextQueue;
}
lock.notifyAll();
}