Этот код обнаружения блокировки EDT сделает эту работу, добавив сторожей.
EventQueueWithWD.java
:
<code>import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
* Alternative events dispatching queue. The benefit over the
* default Event Dispatch queue is that you can add as many
* watchdog timers as you need and they will trigger arbitrary
* actions when processing of single event will take longer than
* one timer period.
* <p/>
* Timers can be of two types:
* <ul>
* <li><b>Repetitive</b> - action can be triggered multiple times
* for the same "lengthy" event dispatching.
* </li>
* <li><b>Non-repetitive</b> - action can be triggered only once
* per event dispatching.</li>
* </ul>
* <p/>
* The queue records time of the event dispatching start. This
* time is used by the timers to check if dispatching takes
* longer than their periods. If so the timers trigger associated
* actions.
* <p/>
* In order to use this queue application should call
* <code>install()</code> method. This method will create,
* initialize and register the alternative queue as appropriate.
* It also will return the instance of the queue for further
* interactions. Here's an example of how it can be done:
* <p/>
* <pre>
* <p/>
* EventQueueWithWD queue = EventQueueWithWD.install();
* Action edtOverloadReport = ...;
* <p/>
* // install single-shot wg to report EDT overload after
* // 10-seconds timeout
* queue.addWatchdog(10000, edtOverloadReport, false);
* <p/>
*
* / открытый класс EventQueueWithWD extends EventQueue {// Mainтаймер приватный финал java.util.Timer timer = new java.util.Timer (true);// Группа информационных полей для описания приватного события final Object EventChangeLock = new Object ();private volatile long eventDispatchingStart = -1;частное энергозависимое событие AWTEvent = null;/ ** * Скрытый служебный конструктор.* / private EventQueueWithWD () {} / ** * Установить альтернативную очередь.* * @ Возврат установленного экземпляра очереди.* / public static EventQueueWithWD install () {EventQueue eventQueue = Toolkit.getDefaultToolkit (). getSystemEventQueue ();EventQueueWithWD newEventQueue = new EventQueueWithWD ();eventQueue.push (newEventQueue);return newEventQueue;} / ** * Запишите событие и продолжите обычную диспетчеризацию.* * @param anEvent событие для отправки.* / protected void dispatchEvent (AWTEvent anEvent) {setEventDispatchingStart (anEvent, System.currentTimeMillis ());super.dispatchEvent (anEvent);setEventDispatchingStart (null, -1);} / ** * Регистрация события и время начала диспетчеризации.* * @param anEvent event.* @param timestamp время начала отправки.* / private void setEventDispatchingStart (AWTEvent anEvent, длинная отметка времени) {synchronized (eventChangeLock) {event = anEvent;eventDispatchingStart = timestamp;}} / ** * Добавить сторожевой таймер.Таймер сработает
listener
*, если событие отправки очереди длиннее указанного *
maxProcessingTime
.Если таймер *
repetitive
, то он вызовет дополнительные * события, если обработка 2x, 3x и более дольше, чем *
maxProcessingTime
.* * @param maxProcessingTime максимальное время обработки.* @param listener listener для событий.Слушатель * получит
AWTEvent
* в качестве источника события.* @param повторяющееся ИСТИНА для запуска последующих событий * для 2x, 3x и последующих периодов.* / public void addWatchdog (long maxProcessingTime, прослушиватель ActionListener, логическое повторение) {Watchdog checker = new Watchdog (maxProcessingTime, listener, повторение);timer.schedule (checker, maxProcessingTime, maxProcessingTime);} / ** * Проверяет, является ли обработка события более длительной, чем * указанный
maxProcessingTime
.Если так, то * слушатель получает уведомление.* / закрытый класс Watchdog extends TimerTask {// Настройки приватного финала long maxProcessingTime;приватный финальный слушатель ActionListener;закрытый финальный логический повтор;// Событие сообщается как "продолжительное" в последний раз.Используется для // предотвращения повторяющегося поведения в неповторяющихся таймерах.private AWTEvent lastReportedEvent = null;/ ** * Создает таймер.* * @param maxProcessingTime максимальное время обработки события * до уведомления слушателя.* слушатель @param слушатель, чтобы уведомить.* @param повторяющееся ИСТИНА для разрешения последующих * уведомлений об одном и том же событии * / private Watchdog (длинный maxProcessingTime, слушатель ActionListener, логический повтор)) {if (listener == null) выдает новое исключение IllegalArgumentException («Listener не может быть нулевым.»);if (maxProcessingTime <0) генерирует новое IllegalArgumentException («Максимальный период блокировки должен быть больше нуля»);this.maxProcessingTime = maxProcessingTime;this.listener = слушатель;this.repetitive = повторяющийся;} public void run () {долгое время;AWTEvent currentEvent;// Получить текущие реквизиты событиясинхронизированный (eventChangeLock) {
time = eventDispatchingStart;
currentEvent = событие;
}
long currentTime = System.currentTimeMillis ();
// Проверяем, обрабатывается ли событие дольше допустимого
if (time! = -1 && (currentTime - time> maxProcessingTime) &&
(повторяющиеся || currentEvent! = lastReportedEvent)) {
listener.actionPerformed (
новый ActionEvent (currentEvent, -1, null));
lastReportedEvent = currentEvent;
}
}
}
}
SampleEQUsage.java
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.Date;
/**
* Sample usage of <code>EventQueueWithWD</code> class.
*/
public class SampleEQUsage extends JFrame
{
public SampleEQUsage()
{
super("Sample EQ Usage");
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().add(new JButton(new AbstractAction("Go")
{
public void actionPerformed(ActionEvent e)
{
System.out.println();
System.out.println(new Date());
try
{
// Sleep for 10 seconds
Thread.sleep(10000);
} catch (InterruptedException e1)
{
}
}
}));
setSize(100, 100);
}
public static void main(String[] args)
{
initQueue();
SampleEQUsage sequ = new SampleEQUsage();
sequ.setVisible(true);
}
// Install and init the alternative queue
private static void initQueue()
{
EventQueueWithWD queue = EventQueueWithWD.install();
// Install 3-seconds single-shot watchdog timer
queue.addWatchdog(3000, new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
System.out.println(new Date() + " 3 seconds - single-shot");
}
}, false);
// Install 3-seconds multi-shot watchdog timer
queue.addWatchdog(3000, new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
System.out.println(new Date() + " 3 seconds - multi-shot");
}
}, true);
// Install 11-seconds multi-shot watchdog timer
queue.addWatchdog(11000, new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
System.out.println(new Date() + " 11 seconds - multi-shot");
}
}, true);
}
}