叫醒等待线程

时间:2013-12-26 00:30:37

标签: java multithreading

这个类与执行者一起工作。事情是,在某些时候我想关闭它,但即使我将terminateRequested更改为“true”它也不会帮助那些线程在“takeTask”中等待,因为此时的向量任务始终为空。 我需要它们以某种方式到达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();

}

4 个答案:

答案 0 :(得分:0)

您需要突破while tasks.isEmpty()){循环并退出while(!terminateRequested){循环

所以我建议你做什么

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

您将其更改为

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

由于我看不到您的giveSolution方法,我无法告诉您必须更改它。

或者,您可以通过InterruptedException方法中的takeTask

答案 1 :(得分:0)

由于您正在使用执行程序服务,因此您可以调用它的shutdownNow方法,该方法将主动关闭线程而无需等待。

根据Is using Object.wait and Object.notify directly a code smell?

将Object.wait和Object.notify与java.util.concurrent组合。

答案 2 :(得分:0)

你需要打破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();

}

答案 3 :(得分:0)

首先,如果你有三个不同的RunnableStudent实例(每个线程的每个实例),并假设任务和terminateRequested是局部变量,你不需要同步。但是你没有在线程之间共享。

其次,如果你正在使用执行程序,你可以使用线程池,这种情况下你不需要等待并通知自己,一旦工作完成,池中的所有线程(池中的n配置的线程数)将等待下一个请求(通过executors.submit / execute)。并且您可以根据您的条件在任何给定点使用shutdown / shutdownNow。

最后回答你的问题,只需将 while循环更改为taketask()中的条件。所有问题都将解决。因为你的等待逻辑仍然适用于run方法中的main while循环。