0

Некоторое время назад мы добавили код в наше приложение, чтобы обнаружить и попытаться восстановить из-за тупика EDT Swing, чтобы пользователь мог как минимум сохранить свои файлы (было бы лучше не иметь тупик, но ...). В Java 1.6 это легко. Обнаружить, что EDT был заблокирован в течение достаточного количества времени, а затем вызвать это из фонового потока:Как заменить или перезапустить тупик Swing EventDispatchThread/EventQueue в настольном приложении Java 8

EventQueue newQ = new EventQueue(); 
Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQ); 

события Новый пользовательский интерфейс будет обрабатываться на новой EventQueue/EDT, и пользователь может сохранить свою работу ,

В Java 8 это не работает, потому что реализация EventQueue.push была изменена для копирования (заблокированного) EventDispatchThread из старой очереди в новую.

+2

Являются ли наблюдаемые взаимоблокировки из-за фактической ошибки Swing или ошибки приложения? – fge

+1

1. Toolkit.getDefaultToolkit(). GetSystemEventQueue(). Push (newQ); == SecondaryLoop, для> = Java7, 2, вы рискуете, используя SystemEventQueue # push, вы можете потерять все события, которые не выполняются с постоянной очередью, уверены, что это необходимо, 3. вывод из рабочего потока должен быть обернутым в простой invokeLater, нет причин для очереди реселлеров (исключая экспериментальную причину, стресс-тестирование :-), 4. Обнаружить, что EDT был заблокирован на достаточное количество времени ---> этого не должно быть, в течение всего жизненного цикла, измените это, GUI должен быть lightweigt во всех случаях – mKorbel

+0

для лучшей помощи, скорее скопируйте SSCCE/MCVE, короткий, выполнимый, компилируемый – mKorbel

ответ

0

Конечно, я всегда могу сделать что-то немного зла:

private static void hackAroundJava8Protections(EventQueue newQ) { 
    try { 
     Field field = newQ.getClass().getDeclaredField("dispatchThread"); 
     field.setAccessible(true); 
     field.set(newQ, null); 
     Method method = newQ.getClass().getDeclaredMethod("initDispatchThread"); 
     method.setAccessible(true); 
     method.invoke(newQ); 
    } catch (Throwable e) { 
     throw new RuntimeException(e); 
    } 
} 

Это начинается новый EventDispatchThread, что позволяет использовать в пользовательском интерфейсе приложения. Мне удалось сохранить данные, как если бы я был пользователем. Я не уверен, что может быть. Может быть, есть менее страшный способ перезапуска заблокированного EDT?

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

  • Нет связанных вопросов^_^