Java:具有后台线程的 GUI 应用程序

Posted

技术标签:

【中文标题】Java:具有后台线程的 GUI 应用程序【英文标题】:Java: GUI application with a background thread 【发布时间】:2010-02-24 18:20:37 【问题描述】:

编辑:为了让事情更清楚-

我有一个连接到远程服务器并更新 GUI 的应用程序。应用程序使用 MVC 模式。

1) 远程服务器可能会发送一条消息来更新我的应用程序的数据模型。

2)GUI控制器类实现PropertyChangeListener接口,监听模型更新,更新GUI视图类

3) 应用程序能够在 GUI 上的用户操作之后将消息发送回远程服务器。这使用从远程服务器接收数据的同一对象。

我目前在我的主要方法中初始化“远程服务器通信”对象和 GUI 类。既然通信对象可以独立更新模型,我应该使用 SwingUtilities.invokeLater() 来初始化这个对象吗?

【问题讨论】:

【参考方案1】:

我不完全确定我能理解你,但无论如何我只有一件事要扔--

确保每次触摸 GUI 时,它都在 AWT 线程上。从理论上讲,这甚至意味着创建 GUI(尽管在实践中,在分配给主线程或其他线程的线程中创建 GUI 很少出现问题,但 sun 确实在某一时刻检测到了问题并建议反对)

无论如何,这意味着您在任何时候希望从不同的线程更新 GUI 时都使用 invokeLater。期间。

(请注意,每当 GUI 通过回调(ActionListener 等)调用您时,该回调始终是 AWT 线程,因此您可以在回调中使用 GUI 做任何您想做的事情。

根据您修改后的消息,我可能会建议,如果您有可能发生线程争用并且正在执行 GUI I/O,则处理它的一种方法是在 invokeLater 中执行所有“有争议”的事情。

虽然在你的主线程中实例化一个 GUI 大部分是合法的(理论上一切都在 setVisible(true) 之前),但如果有任何可能来自另一个线程的冲突,invokeLater 将在一种非常确定的方式。

【讨论】:

比尔-谢谢。我已经稍微简化了我最初的问题以使其更清楚。【参考方案2】:

我的问题是:鉴于供应商代码初始化了自己的连接线程,我是否仍应将所有远程通信代码(解析事件、更新模型、将消息发送回远程应用程序)显式地放在与初始化 GUI 的代码分开线程?

是的

如果我理解正确,就会发生这种情况。

供应商库将启动自己的线程并最终回调您代码上的给定方法。

这将更新您的应用。 3rd 方库中已经使用了一个线程,这就足够了。

如果您的应用又必须与供应商远程服务器通信,则您需要使用自己的线程。那么答案是肯定的。

如果您只是对供应商库发送给您的内容“做出反应”,则不需要单独的线程。

【讨论】:

奥斯卡,感谢您的回复。是的,该应用程序还与远程服务器通信。我将不得不考虑重新设计。【参考方案3】:

SwingUtilities.invokeLater() 将直接在 GUI 的 Event Dispatch 线程上运行您的 Runnable。

换句话说,从不使用它来运行后台任务,因为它会阻止 GUI 响应。改为子类SwingWorker,如Sun 的tutorial 或其他背景Threads 所示。

【讨论】:

以上是关于Java:具有后台线程的 GUI 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何将 PyQt 插槽从后台线程连接到 gui 线程

使用 pthreads 时的后台线程(很好,优先级)

如何在带有 Swing gui 的后台线程中使用 jdbc

Java 7 Concurrency Cookbook 翻译 第一章 线程管理之四

Android:使用“进度”GUI在后台线程中从网络加载数据? [复制]

PyQt中带有QThread的后台线程