【问题标题】:prevent GUI from freezing and have button to cancel operation/kill thread防止 GUI 冻结并有按钮取消操作/杀死线程
【发布时间】:2013-04-29 10:55:58
【问题描述】:

这是我想要做的:

我有一个JFrame,其中包含一个JTextArea,显示正在进行的连接的更新。如果用户想取消连接,应该能够按其右侧的JButton。但是,由于连接在尝试连接时阻塞(使用)线程,所以 GUI 会冻结。我正在寻找快速修复。可能在单独的线程上拥有ActionListener?尽管我可以基本使用可运行对象,但我对线程没有太多经验。

答案是否与使用 EDT 有关?如果是这样应该如何实现?

PS 澄清一下,按钮应该能够杀死创建连接的线程。看完好像是一个executorService。可以帮忙吗?是的?还是根本没有?

【问题讨论】:

  • 所以不能在连接上使用超时参数?
  • 这实际上是在建立连接并且设备使用文本协议进行通信之后。如果其他设备没有响应,我希望能够取消尝试,即我会在尝试从网络读取流时卡住。

标签: java multithreading swing


【解决方案1】:

建议先熟悉 Swing(或几乎任何 UI 框架)和多线程。这是餐巾纸版本:

  • 对 UI 的任何修改或从中读取(例如,获取文本字段的值)必须在 UI 线程上完成(有时也称为“Swing Thread”或“Event Dispatch Thread”(EDT)
  • 任何阻塞或长时间运行的操作(如网络通信)不得在 UI 线程上运行。否则,它们将阻止按钮工作、阻止更新文本等。
  • 在 Java 中,ExecutorService 及其朋友可以相对轻松地让长时间运行或阻塞的东西在后台线程上运行
  • 如果后台线程发生需要您更新 UI 的事情,请将与 UI 相关的代码封装在 EventQueue.invokeLater 调用中。这将确保您传递的 Runnable 在 UI 线程上执行。

SwingWorker 类封装了这个逻辑,并为更简单的情况提供了一个易于使用的帮助器。

第一次这样做时,可能会有点令人生畏,但彻底理解这一点是值得的,因为它不仅适用于 Swing,也适用于任何其他 UI 代码。

【讨论】:

    【解决方案2】:

    为了澄清,按钮应该能够杀死创建连接的线程。看完好像是一个executorService。可以帮忙吗?是的?还是根本没有?

    是的

    • while(localBooleanVariable)Runnable#Thread,纯线程

    • 通过使用SwingWorker.cancel()

    • 最简单的可能是SwingWorker,因为可以取消并且从publish() 输出,progress() 在 EDT 上

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多