EventQueue несовместимые идентификаторы - PullRequest
4 голосов
/ 25 августа 2011

У меня проблема со следующим примером кода, который показывает несовместимое поведение для 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 Ответ

2 голосов
/ 25 августа 2011

Этот поток диспетчеризации событий AWT может быть отключен, когда он больше не нужен ( эта страница описывает как спецификацию, так и поведение фактической реализации в JDK 7).

Это, кажется, происходит здесь: вы используете систему EventQueue для обработки одного события.Тогда ничего больше не нужно (без компонентов AWT / Swing, ...).Через некоторое время он отключается.

Затем, когда вы снова используете EventQueue, другой поток начинает играть эту роль.

Итак, что происходит здесь, так это то, что ваш Runnable.run()методы do выполняются в двух отдельных потоках . Оба потока являются "потоком диспетчеризации событий AWT", только в разное время в жизненном цикле JVM.

Может быть, особый случай с использованием EventQueue.isDispatchThread() будетбыть возможным решением.

...