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 或其他背景Thread
s 所示。
【讨论】:
以上是关于Java:具有后台线程的 GUI 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
Java 7 Concurrency Cookbook 翻译 第一章 线程管理之四