0

我在尝试从另一个线程暂停线程执行时遇到问题。我已经阅读了 java 文档和一些堆栈溢出示例,但似乎仍然有些迷茫。

很多情况和我一样;我有一个 gui,它产生一个线程来做一些工作,以便它可以保持对用户的响应。在某些时候,用户做了一些事情,希望在工作线程执行下一条语句之前停止它。然后过了一段时间,继续它的工作。

我已阅读waitnotify文档Threads,这似乎是对上述问题的简短回答(?)。

根据我的 IDE(netbeans)告诉我的内容,我必须在同步块中调用wait和。notify

因此,当按下开始暂停按钮时,这就是我在 JFrame 中的内容。automator是我Thread想要暂停的对象。它static final在我的 JFrame 中声明。firstRunDone只是第一次m_jbStartPause按下的标志,所以automator可以启动而不通知。

OnStartPauseButton()
{
    synchronized(automator)
    {
         if(!running)
         {
              this.m_jbStartPause.setText("Pause");
              running = true;
              if(firstRunDone)
                  automator.notify();
              else
                  automator.start();
              firstRunDone = true;
         }
         else 
         {
             this.m_jbStartPause.setText("Start");
             running = false;
             try { automator.wait(); }  catch (InterruptedException ex) {}
         }
    }
}

我的问题是当我第一次尝试暂停线程时。我可以点击开始,自动机启动,但是当我点击暂停时,所发生的只是 JFrame 冻结,自动机继续工作。

我使用同步错误吗?是否automator需要任何处理代码?

4

2 回答 2

1

以下是问题

try { automator.wait(); }  catch (InterruptedException ex) {}

这将导致线程(您的 GUI)线程等待而不是自动机。JAVA 文档说

wait()..导致当前线程一直等待,直到另一个线程为此对象调用 notify() 方法或 notifyAll() 方法,或者某个其他线程中断了当前线程,或者已经过了一定的实时时间

这就是为什么您的 JFrame 似乎被冻结并且自动机继续运行的原因。您需要在 automator 中构建一种机制来轮询标志的状态以查看它是否需要继续工作。您的 GUI 线程应该更改标志的状态以停止 automator 工作。.

于 2013-09-03T04:11:22.210 回答
1
  • 你最好使用SwingUtilities.invokeLater来更新 UI 而不是使用你的工作线程

  • 如果您需要“取消”线程,则需要将“运行”标志设置为volatile

  • 我建议不要使用“同步”,而是使用ReentrantLock及其条件

于 2013-09-02T20:25:23.167 回答