2010-05-10 4 views
1

Есть ли более элегантный способ сделать то, что я делаю ниже? То есть, есть более элегантный способ, чем опрос и сон, опрос и сон, и так далее, чтобы знать, когда метод Runnable.run() был вызван через invokeLater()?Ожидание invokeLater() будет называться

private int myMethod() { 
    final WaitForEventQueue waitForQueue = new WaitForEventQueue(); 
    EventQueue.invokeLater(waitForQueue); 
    while (!waitForQueue.done) { 
     try { 
      Thread.sleep(10); 
     } catch (InterruptedException ignore) { 
     } 
    } 

    return 0; 
} 

private class WaitForEventQueue implements Runnable { 
    private boolean done; 

    public void run() { 
     // Let all Swing text stuff finish. 
     done = true; 
    } 
} 
+0

Для того, что бы этот код не выполнялся на двух уровнях: (1) он не является потокобезопасным, потому что ожидающий поток никогда не сможет «увидеть» обновление до «done» (см. Модель памяти Java для V5 +) и (2) опрос обычно является плохим решением, особенно на языке, который имеет такой простой механизм ожидания/уведомления (см. Object.wait и др.). –

ответ

2

Если вы хотите подождать, почему бы не позвонить invokeAndWait, а не реализовать его самостоятельно?

+0

Потому что invokeAndWait вызывает взаимоблокировки и оживления и в основном ест котят на завтрак. – Trejkaz

+0

@ Трейказ, не совсем мой опыт, но я уверен, что предлагаемый код не будет улучшением. – Yishai

+0

Наверное, нет, хотя я действительно удивляюсь. Поскольку он не использует блокировку, может быть, он не будет заторможен. Тем не менее, я думаю, что это покажет эту другую проблему, где она не зашла в тупик, но никогда не вернется. – Trejkaz

0

Вместо того, чтобы ждать завершения потока, то почему бы не просто интерфейс отображения блесну или что-то, и есть нить вызвать событие, когда это будет сделано.

+0

Hi Justin, Спасибо за предложение, но не могли бы вы быть более конкретным (например, показать пример кода), насколько «поток вызывает [событие] событие, когда это делается»? –

5

Лучшим способом было бы использовать FutureTask (который реализует Runnable и Future) и переопределяет его событие done(), чтобы что-то сделать, когда закончите.

Кроме того, запустите это как отдельный поток (или используйте Executor), если он не выполняет манипуляции с графическим интерфейсом, а не использует AWT EventQueue.

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