简体   繁体   English

Java,正确使用wait和notify来暂停从另一个线程执行线程

[英]Java, using wait and notify properly to pause thread execution from another thread

I have an issue trying to pause a threads execution from another thread. 我有一个问题试图从另一个线程暂停线程执行。 I have read the java docs and a few stack-overflow examples and still seem to be a little lost. 我已经阅读了java文档和一些堆栈溢出示例,但似乎仍然有点迷失。

Many cases are just like mine; 很多情况就像我的; I have a gui that spawns a thread to do some work so it can stay responsive to the user. 我有一个gui,它产生一个线程来做一些工作,所以它可以保持对用户的响应。 At some point the user does something that makes it desirable to just stop the worker thread before it executes its next statement. 在某些时候,用户会做一些事情,这样就可以在执行下一个语句之前停止工作线程。 And then after sometime, continue its work. 然后过了一段时间,继续工作。

I have read the wait and notify documentation for Threads , and this seems to be the short answer to the question above(?). 我已经阅读了Threadswaitnotify文档,这似乎是上述问题的简短答案(?)。

And from what my IDE (netbeans) tells me, I must call wait and notify inside a synchronized block. 从我的IDE(netbeans)告诉我的内容,我必须在同步块中调用waitnotify

So here is what I had in my JFrame for when my start pause button was pressed. 所以这就是我在JFrame中按下开始暂停按钮的时间。 automator is my Thread object that I want paused. automator是我想要暂停的Thread对象。 Its declared as static final in my JFrame. 它在我的JFrame中声明为static final firstRunDone is just a flag for the first time the m_jbStartPause is pressed, so the automator can be started and not notified. firstRunDone只是第一次按下m_jbStartPause时的m_jbStartPause ,因此可以启动automator而不通知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) {}
         }
    }
}

My problem is with when I first try to pause the thread. 我的问题是当我第一次尝试暂停线程时。 I can hit start and the automator starts, but when I hit pause all that happens is the JFrame freezes and the automator continues doing its work. 我可以点击开始并且自动变速器启动,但是当我点击暂停时,所有发生的事情都是JFrame冻结并且自动变速器继续执行其工作。

Am i using syncronized wrong? 我使用同步错了吗? Does automator need any handling code? automator需要任何处理代码吗?

  • you'd better use SwingUtilities.invokeLater in order to update UI instead of using your worker thread 你最好使用SwingUtilities.invokeLater来更新UI而不是使用你的工作线程

  • if you need to 'cancel' your thread, you need to make your "running" flag as volatile 如果你需要'取消'你的线程,你需要将你的“运行”标志变为易失性

  • instead of using "synchronized", I'd suggest to use ReentrantLock and it's conditions 而不是使用“同步”,我建议使用ReentrantLock及其条件

FOllowing line is the issue FOllowing line就是问题所在

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

This will cause the thread (YOUR GUI) thread to wait not the automator. 这将导致线程(您的GUI)线程不等待自动机。 JAVA docs says JAVA文档说

wait()..Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed wait()..使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或者某个其他线程中断当前线程,或者已经过了一定量的实时

That's why your JFrame appears to be frozen and automator keeps running. 这就是为什么你的JFrame似乎被冻结并且automator继续运行的原因。 You need to build a mechanism in automator that polls the status of a flag to see if it needs to continue its work..and your GUI thread should change the status of the flag to stop automator from working. 您需要在automator中构建一个机制来轮询标志的状态以查看它是否需要继续其工作......并且您的GUI线程应该更改标志的状态以停止自动机的工作。 .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM