2015-04-14 3 views
15

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

Если я возьму дамп потока, есть 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) 

Нить они ждут исполняемом

"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-материал, но это делается с помощью библиотеки, которую я использую.

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

Спасибо!

+0

1. Вы слышали о SecondaryLoop, 2. но «принимаете 100% -ный процессор, но, похоже, ничего не делаете». говорить о JProfiler, 3. без SSCCE/MCVE isn 'answerable, 4. 'java.awt.EventQueue.isDispatchThreadImpl (EventQueue.java: 1019) talk about isEventDispatchThread возвращает false', или события, выполняемые в EDT, не имеют бизнеса там 5. Не знаю, без событий из текущего EDT или исключения из RepaintManager – mKorbel

+0

1) Я раньше не слышал о SecondaryLoop. Я посмотрел его, но сам я не использую AWT, это библиотека, которую я использую, которая вызывает метод. 2) Я не использовал JProfiler, я использовал JVisualVM, он предоставил мне threaddump, на котором были показаны фрагменты. 3) Я не могу воспроизвести его, к сожалению. Это была проблема, которую я имел в производстве, все, что у меня есть, - это дамп потока, поэтому я не могу предоставить SSCCE. 4-5) Боюсь, я не понимаю их. –

+1

Кто устанавливает значение eq.nextQueue в null? Если никто не установит его, цикл будет работать бесконечно, а CPU 100% возможен. Если да, и если это делается каким-то другим потоком, то sq.nextQueue должен быть неустойчивым. Если этот поток не может выбрать значение, так как поток может кэшировать значение eq.nextQueue, где цикл будет работать бесконечно снова и возможно 100%. – Eranda

ответ

0

Ваша проблема - проблема взаимоблокировки (see 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(); 
} 
+0

Код, приведенный выше, является частью Java SDK (java.awt.EventQueue.isDispatchThreadImpl (EventQueue.java:1024)), я не могу или не хочу - изменить этот код. –

1

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

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

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

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

+0

Я никогда не думал об этом, но действительно возможно, что библиотека, которую я использую, имеет этот EventQueue.push. Это не библиотека с открытым исходным кодом, поэтому мне придется с ними проверить. –

Смежные вопросы