1

Is there a more elegant way to do what I'm doing below? That is, is there a more elegant way than polling and sleeping, polling and sleeping, and so on to know when a Runnable.run() method has been called via 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;
    }
}
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Paul Reiners
  • 8,576
  • 33
  • 117
  • 202
  • For whatever it's worth this code fails on two levels: (1) it is not thread-safe because the waiting thread may never "see" the update to `done` (see the Java Memory Model for V5+), and (2) polling is generally a bad solution, especially in a language that has such an easy wait/notify mechanism (see Object.wait, et al). – Lawrence Dol May 10 '10 at 19:15

3 Answers3

5

A better way would be to use a FutureTask (which implements Runnable and Future) and override its done() event to do something when finished.

Also, start this as a separate thread (or use an Executor) if it's not doing GUI manipulation, rather than using the AWT EventQueue.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
3

If you want to wait, why not call invokeAndWait rather than implement it yourself?

Yishai
  • 90,445
  • 31
  • 189
  • 263
  • Because invokeAndWait causes deadlocks and livelocks and basically eats kittens for breakfast. – Hakanai Mar 21 '14 at 02:13
  • @Trejkaz, not really my experience, but I'm sure the suggested code wouldn't be an improvement. – Yishai Mar 21 '14 at 02:27
  • Probably not, although I do wonder. Because it isn't using a lock, maybe it won't deadlock. However, I do think it will exhibit this other issue where it isn't deadlocked but never returns. – Hakanai Mar 21 '14 at 02:38
0

Instead of waiting for the thread to finish, why not just have the UI display a spinner or something, and have the thread call an event when it is done.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
  • Hi Justin, Thanks for the suggestion, but could you be more specific (i.e. show some sample code) as far as the "thread call[ing] an event when it is done" part? – Paul Reiners May 10 '10 at 18:40