EventQueue несовместимые идентификаторы
У меня есть проблема со следующим примером кода, который показывает противоречивое поведение для EventQueue:
public static void main( String[] args ) throws InvocationTargetException, InterruptedException {
final long[] id1 = new long[ 1 ];
final long[] id2 = new long[ 1 ];
EventQueue.invokeAndWait( new Runnable() {
@Override public void run() {
id1[ 0 ] = Thread.currentThread().getId();
}
} );
Thread.sleep( 5000 );
EventQueue.invokeAndWait( new Runnable() {
@Override public void run() {
id2[ 0 ] = Thread.currentThread().getId();
}
} );
System.out.println( "id1 = " + id1[0] );
System.out.println( "id2 = " + id2[0] );
if(id1[0]!=id2[0]){
System.out.println("These ID's don't match, even though they were retrieved from the same thread.");
}
}
По сути, он получает идентификатор потока очереди событий, ждет 5 секунд, а затем снова получает идентификатор.
По какой-то причине идентификаторы не совпадают. Видимо, EventQueue был разрушен и воссоздан. Это нормальное поведение? Это где-то задокументировано? Это ошибка? Даже если это был другой экземпляр, не должен ли он иметь такой же идентификатор?
Если я не выполню Thread.sleep
, идентификаторы будут совпадать.
Мой другой вопрос: как я могу обойти это? Я использую объект, доступ к которому можно получить только в потоке создания. Если это случайная очередь (которой это не обязательно должно быть), я должен быть в состоянии проверить, является ли она все еще очереди событий.
1 ответ
Этот поток диспетчеризации событий AWT может быть отключен, когда он больше не нужен (на этой странице описаны как спецификация, так и поведение фактической реализации в JDK 7).
Это, кажется, происходит здесь: вы используете систему EventQueue
обрабатывать одно событие. Тогда больше ничего не нужно (без компонентов AWT/Swing, ...). Через некоторое время он отключается.
Затем, когда вы используете EventQueue
снова другая нить начинает занимать эту роль.
Так что здесь происходит, что ваш Runnable.run()
методы выполняются в двух разных потоках. Оба потока являются "потоком отправки событий AWT", просто в разное время в жизненном цикле JVM.
Может быть, специальный корпус это с помощью EventQueue.isDispatchThread()
было бы возможным решением.