简体   繁体   English

唤醒等待线程

[英]wake up waiting threads

this class works with an executor. 该课程与执行者一起工作。 the thing is that at some point i want to shut it down, but even if i'm changing the terminateRequested to "true" it wont help those threads stuck waiting in "takeTask" because the vector tasks at that point is always empty. 事实是,在某个时候我想关闭它,但是即使我将terminateRequested更改为“ true”,它也不会帮助那些在“ takeTask”中等待的线程,因为此时的矢量任务始终为空。 i need them somehow to get to "e.shutDown()" line in run() 我需要它们以某种方式到达run()中的“ e.shutDown()”行

public class RunnableStudent implements Runnable{

public void run() {

    while(!terminateRequested){

        this.takeTask();
        this.giveSolution();

    }


    e.shutdown();

}


private synchronized void takeTask(){


          while(tasks.isEmpty()){
               try {

                 this.wait();
              } catch (InterruptedException e) {

                 e.printStackTrace();
              }
          }

         DoSomeWork();
}

public synchronized void shutDown(){


    terminateRequested = true;
    this.notifyAll();

}

You will need to break out of your while tasks.isEmpty()){ loop and out of your while(!terminateRequested){ loop 您将需要跳出while tasks.isEmpty()){循环,而跳出while(!terminateRequested){循环

so I suggest that when you do 所以我建议你做的时候

} catch (InterruptedException e) {
     e.printStackTrace();
}

you change it to 您将其更改为

} catch (InterruptedException e) {
     terminateRequested = true;
     return;
}

As I can not see your giveSolution method I can not tell you have to change it. 由于看不到您的giveSolution方法,因此无法告诉您必须更改它。

Alternatively you could through the InterruptedException from the takeTask method. 另外,您可以通过takeTask方法中的InterruptedException

Since you're using executor service you can call it's shutdownNow method that is going to actively shut down threads without waiting. 由于您使用的是执行程序服务,因此可以调用它的shutdownNow方法来主动关闭线程,而无需等待。

Combining Object.wait and Object.notify with java.util.concurrent smells as per Is using Object.wait and Object.notify directly a code smell? 将Object.wait和Object.notify与java.util.concurrent气味组合在一起, 是否直接使用Object.wait和Object.notify产生代码气味?

You need break the loop of while(tasks.isEmpty()) so change the code like this: 您需要打破while(tasks.isEmpty())的循环,因此需要更改代码,如下所示:

public class RunnableStudent implements Runnable{

 private Thread thread;
 public void run() {

    thread = Thread.currentThread();
    while(!terminateRequested){

        this.takeTask();
        this.giveSolution();

   }


   e.shutdown();

 }

 private synchronized void takeTask(){


      while(tasks.isEmpty()){
           try {

             this.wait();
          } catch (InterruptedException e) {
             break;
          }
      }

     DoSomeWork();
}

public synchronized void shutDown(){

     terminateRequested = true;
     thread.interupt();

}

First, if you are having three different RunnableStudent instance ( each instance per thread) and assumed the tasks and terminateRequested are local variables , you dont need to syncronized .becuase there is nothing you are sharing between threads. 首先,如果您拥有三个不同的RunnableStudent实例(每个线程每个实例),并且假定任务和TerminateRequested是局部变量,则无需同步。因为线程之间没有共享的对象。

Second , if you are using executors , you can use thread pool , that case you dont need to do wait and notify yourself , once the work is completed all the threads ( n number of threads configured while pool iniitalize) in pool will wait for next request ( through executors.submit/execute) . 其次,如果您使用执行程序,则可以使用线程池,这种情况下您无需等待并通知自己,一旦工作完成,则池中的所有线程(在池初始化时配置了n个线程)将等待下一个请求(通过executors.submit / execute)。 And you can use shutdown / shutdownNow at any given point based on your condition. 而且,您可以根据自己的情况在任何给定点使用shutdown / shutdownNow。

Finaly to answer your question, just change the while loop to if conditon in taketask(). 最后回答您的问题,只需将while循环更改为taketask()中的if条件。 All your problems will resolve . 您所有的问题都会解决。 because your waiting logic will still holds good with main while loop in run method. 因为您的等待逻辑在run方法中的main while循环中仍然会很好。

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

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