Бесконечный цикл в EventQueue.isDispatchThread()

У меня есть Java-программа, принимающая 100% -ный процессор, но, похоже, ничего не делая.

Если я беру дамп потока, есть 4 потока (из пула из 5), ожидающих блокировки.

"Incoming WorkPool 5" - Thread [email protected]
   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" [email protected]
    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 [email protected]
   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 EventQueue, пытающихся получить тот же pushpoplock.

VM работает как служба, поэтому ему не следует пытаться использовать AWT, но это делается с помощью библиотеки, которую я использую.

Любые идеи? Могу ли я предотвратить это?

Спасибо!

Ответы

Ответ 1

Есть ли вероятность, что push(EventQueue newEventQueue) вызывается вашей прикладной программой и толкает тот же eventQueue? Если да, то this и его nextQueue будут такими же объектами, и они будут работать в бесконечном цикле, потребляющем CPU до 100%.

Из трассировки стека видно, что работает хотя бы один поток. Так что это не вопрос DEADLOCK.

Из 100% -ного подсчета потребления ЦП и его состояния как RUNNABLE, очевидно, что он делает бесконечный цикл.

Код может перейти в бесконечный цикл тогда и только тогда, когда nextQueue имеет значение, уже существующее в цепочке (или this). Это может быть проблемой приложения. Благодарю.

Ответ 2

Ваша проблема - проблема взаимоблокировки (см. wikipeida).

Deadlock situation here Как вы можете видеть выше, ваши два события EventQueues (здесь R1 и R2) находятся в ситуации взаимоблокировки - каждый из них заявляет один ресурс и не может работать дальше, пока другой требовал другой ресурс. Оба ждут друг друга бесконечно.

Вы можете решить эту проблему с помощью разных подходов:

Попробуйте изменить библиотеку, вы правы, что библиотека не должна пытаться делать awt если это не библиотека, тесно связанная с awt. На таких платформах, как github, много библиотек, я уверен, что вы найдете другая библиотека, чтобы заменить вашу, которая вызывает ошибку.

Если вы можете редактировать свой код, чтобы добавить мониторинг, вы предотвращая любые взаимоблокировки.

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