【问题标题】:Gui blocked when starting Thread from button clicked event从按钮单击事件启动线程时 Gui 被阻止
【发布时间】:2014-12-16 02:04:31
【问题描述】:

这可能是一个基本问题,但我一直坚持。

我想进一步了解为什么当我从按钮单击事件启动新线程(可运行)时 GUI 会被阻止?我该如何克服呢?我做错了什么?

下面的代码在单击时会启动一个新线程,但是我想在单击该按钮时更改文本框的背景颜色,但我无法做到这一点,而且主 ui 在该线程时无响应运行时,我相信我通过启动一个新线程来正确实现它,以免阻塞主 ui,但我一定错过了一些东西,因为这显然是不希望的行为。

代码:

private void startButtonEvent(ActionEvent evt) {

         ntmStatusText.setBackground(Color.green);// textbackground I want to change

        //Start Ntm Thread
         Thread thread = new Thread(new NtmThread());
           thread.start();

           while(thread.isAlive()){

               System.out.println("thread still working");

           }
           System.out.println("thread stopped");

    }

如何阻止我的 Ui 在运行线程时变得无响应?

【问题讨论】:

  • 'while(thread.isAlive()){'NONONO!不要在 GUI 事件处理程序中等待。不要循环,不要加入(),不要等待事件。不要! GUI 处理程序线程是一个状态机。不要在里面等。不要循环任何标志。不要循环任何线程状态。不要在 GUI 事件处理程序中等待。从来没有。
  • 好的,这就是解释,我永远不会再这样做了!感谢您的帮助。
  • :) 好吧,我可能有点醉了……
  • @MartinJames 派对!!
  • 没问题,这证明了你的知识能够在有点醉的时候回答,另一方面,我可能应该考虑不要在早上 0100 尝试学习编程 :) 哈哈。

标签: java multithreading swing runnable


【解决方案1】:

while(thread.isAlive()){ 是一个阻塞方法,它会停止事件调度线程,直到Thread.isAlive 变为 false,这会阻止它能够处理添加到事件队列中的新事件,包括绘制请求

这是因为 Swing 是单线程环境,这意味着有一个线程负责处理进入程序的所有事件。这由事件调度线程处理。

所有用户生成的事件都在 EDT 内进行管理(也就是说,您的 actionPerformed 方法,在 EDT 的上下文中被调用)

Concurrency in Swing

然后,您要么向您的NtmThread 提供回调功能,或者考虑使用SwingWorker 并将PropertyChanegListener 附加到属性state 的监视器并检查SwingWorkers 状态是否具有改为DONE

详情请见Worker Threads and SwingWorker

例如:How to use jProgress bar for ProcessBuilder process?

【讨论】:

  • 感谢您对这样一个菜鸟问题的出色回答,我的下一个问题是如何更新线程进度的用户界面,但您已经了解了,谢谢!
【解决方案2】:

您已经创建了一个新线程,但您正在使用当前线程来检查创建的线程是否处于活动状态while(thread.isAlive()){
因此,在您创建的线程没有停止之前,当前线程永远不会退出循环。
而您当前的这个线程负责完成所有 gui 工作,但您让它卡住了,这就是您的 GUI 被阻止的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多