防止GUI冻结,并有按钮取消操作/杀死线程

时间:2013-04-29 10:55:58

标签: java multithreading swing

以下是我要做的事情:

我有一个JFrame,其中包含JTextArea显示正在进行的连接的更新。如果用户想要取消连接,则应该能够按下其右侧的JButton。但是,由于连接在尝试连接时阻塞(使用)线程,因此GUI将被冻结。我正在寻找快速解决方案。可能在单独的线程上有ActionListener吗?虽然我可以基本使用runnables,但我对线程没有多少经验。

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

PS澄清一下,按钮应该可以杀死创建连接的线程。看完后似乎是一个executorService。可以帮忙吗?是?或者根本没有?

2 个答案:

答案 0 :(得分:5)

建议首先加快Swing(或几乎任何UI框架)和多线程的速度。这是餐巾纸版本:

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

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

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

答案 1 :(得分:1)

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

  • while(localBooleanVariable)Runnable#Thread内,普通线程

  • 使用SwingWorker.cancel()

  • 最简单的可能是SwingWorker,因为可以取消,publish()progress()的输出是在美国东部时间