2010-05-10 59 views
1

有没有更好的方法来做我在下面做的事情?也就是说,是否有比投票和睡眠,投票和睡眠更优雅的方式,以便知道何时通过invokeLater()调用了Runnable.run()方法?等待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 Memory Model for V5 +)和2)轮询通常是一个不好的解决方案,特别是在具有这种简单的等待/通知机制的语言中(见Object.wait等)。 – 2010-05-10 19:15:23

回答

2

如果你想等待,为什么不打电话invokeAndWait而不是自己实施它?

+0

因为invokeAndWait导致死锁和活锁,并基本上吃早餐的小猫。 – Trejkaz 2014-03-21 02:13:16

+0

@Trejkaz,不是我的经验,但我确信建议的代码不会有所改进。 – Yishai 2014-03-21 02:27:21

+0

可能不是,虽然我很好奇。因为它没有使用锁,所以它可能不会死锁。不过,我认为它会出现这个问题,它不会死锁,但永远不会返回。 – Trejkaz 2014-03-21 02:38:11

0

而不是等待线程完成,为什么不只是让用户界面显示一个微调或什么,并让线程在完成时调用一个事件。

+0

嗨,贾斯汀, 感谢您的建议,但你可以更具体(即显示一些示例代码),只要“线程调用一个事件,当它完成”的一部分? – 2010-05-10 18:40:27

5

更好的方法是使用FutureTask(实现Runnable和Future)并覆盖它的done()事件来完成某些操作。

另外,如果它不是在执行GUI操作,而是使用AWT EventQueue,则将其作为单独的线程启动(或使用Executor)。