2012-02-22 22 views
4

在我的带有Swing GUI的Java应用程序中,我想要实现以下功能。Java Swing应用程序:如何从GUI线程获取数据到另一个线程?

有一个非GUI线程正在运行,执行一些工作。有一点,这个线程需要用户输入才能继续。然后,我想对GUI进行一些更改,等待特定的GUI操作(如用户按下OK按钮),从GUI获取输入数据到非GUI线程,并让它继续计算。

环顾四周,我发现了很多关于如何从另一个线程上的Swing GUI线程启动执行(长时间运行)任务的信息,但没有解决我的问题。

SwingUtilites.invokeAndWait听起来像它的工作,但首先,它需要一个Runnable参数,而不是一个Callable的,所以返回的结果没有直接的方式,第二,它没有解决的等待一定的问题GUI事件。

我意识到我可以用自己的解决方案来弥补自己的解决方案。一个CountDownLatch,但对我来说,这个问题似乎足够频繁,因为有一个标准的解决方案。

所以,我的问题是:这是一个真正常见的问题,如果是的话,是否有标准库/库中的解决方案?如果没有标准的解决方案,你会如何解决它?如果这个问题不经常发生,为什么不呢?

+0

查看类似的问题http:// stackoverflow。com/questions/3981924/how-to-retrieve-a-value-that-must-be-calculated-on-another-thread – 2014-02-19 01:49:51

回答

6

启动GUI更改非常简单,所以我假设你只是询问有关将数据返回给工作线程的问题。

首先,创建一个Blocking Queue。让工作者线程在队列上调用take(),并将其阻塞。在GUI空间中,一旦用户输入有效的输入,将其放入队列offer(),工作线程将接收数据并可以继续。

+0

好主意,谢谢。 – sandris 2012-02-22 16:16:53

+1

+1用于使用更高级别的抽象,而不是显式锁定。如果你用这种方式处理多线程,它就是*方式方式*更容易获得正确的代码(没有细微的错误)。 – 2012-02-22 18:24:16

1

我认为,你可以使用的ExecutorService,你也可以通过未来界面跟踪任务的进度。

+0

我没有任务来跟踪进度。我想等待用户输入。 – sandris 2012-02-22 16:01:17

0
final bool result = doSomething(); 
SwingUtilities.invokeLater(new Runnable(){ 
     //Runnable method implementation. 
     //use result in your method like local var. 
    }); 

请确保您的共享数据是同步的使用锁定对象。 如果您需要将参数传递给Runnable,只需将您的局部变量设置为最终, 并在run方法中使用它们。

+0

我不想将参数传递给'Runnable',我想从那里得到结果。我知道可以通过改变线程安全对象来实现这一点,但从方法获取返回值会更清晰。 – sandris 2012-02-22 16:09:43

+0

然后,只需创建一个类成员并在可运行对象中对其进行更改即可。唯一需要的是同步这个对象。 – AlexTheo 2012-02-22 19:19:07

1

java.awt.EventQueue.invokeLater很适合在AWT EDT上运行代码。可能最好是复制可变数据或更好地使用不可变数据。锁可能,但有点冒险。

如果你的其他线程是一个事件调度循环,你可以为你的线程实现类似invokeLater(但不要使它成为静态!)。可能在一些对线程行为有意义的接口后面使用它 - 所以它是真实的操作而不是run,它被指定为做任何它喜欢的事情。如果你的线程要阻塞,那么BlockQueue是好的,但不要阻止来自AWT EDT。

java.awt.EventQueue.invokeAndWait就像使用锁。可能你会使用另一个锁。或者也可以像你自己的线索那样锁定invokeAndWait。如果你不这样做,无论如何AWT都会使用锁。所以,不受控制的嵌套锁定,可能意味着死锁。请勿使用invokeAndWait

+0

那么你基本上说没有现成的解决方案,并且将'SwingUtilities.invokeLater'与我自己的锁结合使用是唯一的方法吗? – sandris 2012-02-22 16:06:59

相关问题