9

Started several worker threads , need to notify them to stop. Since some of the threads will sleep for a while before next round of working, need a way which can notify them even when they are sleeping.

If it was Windows programming I could use Event and wait functions. In Java I am doing this by using a CountDownLatch object which count is 1. It works but don't feel elegant, especially I have to check the count value to see if need to exit :

run(){
    while(countDownLatch.count()>0){
            //working
            // ...
            countDownLatch.wait(60,TimeUnit.SECONDS);
    }
}

Semaphore is another choice, but also don't feel very right. I am wondering is there any better way to do this? Thank you.

HourseArmor
  • 139
  • 1
  • 2
  • 5
  • 1
    This is not quite the answer you are looking for, but you should use the thread pools (java.util.concurrent). I'm nearly sure they can do what you want and they are bug free and you can use your time to develop other things. – toto2 Jul 28 '11 at 13:34
  • Do you want to stop all the threads, or do you only want to stop a few? – Moonbeam Jul 28 '11 at 13:49
  • 1
    @Moonbeam I need to stop them individually,so thread pool doesn't seem be a feasible solution. – HourseArmor Jul 28 '11 at 15:22
  • @HourseArmor, Then a majority, if not all the answers given are suitable. – Moonbeam Jul 28 '11 at 15:24

5 Answers5

9

Best approach is to interrupt() the worker thread.


Thread t = new Thread(new Runnable(){
    @Override
    public void run(){
        while(!Thread.currentThread().isInterrupted()){
            //do stuff
            try{
                Thread.sleep(TIME_TO_SLEEP);
            }catch(InterruptedException e){
                Thread.currentThread().interrupt(); //propagate interrupt
            }
        }
    }
});
t.start();

And as long as you have a reference to t, all that is required to "stop" t is to invoke t.interrupt().

Moonbeam
  • 2,283
  • 1
  • 15
  • 17
0

Use the builtin thread interruption framework. To stop a worker thread call workerThread.interrupt() this will cause certain methods (like Thread.sleep()) to throw an interrupted exception. If your threads don't call interruptable methods then you need to check the interrupted status.

In the worker thread:

run() {
    try {
        while(true) {
            //do some work
            Thread.sleep(60000);
        }
    }
    catch(InterruptedException e) {
        //told to stop working
    }
}
brain
  • 5,496
  • 1
  • 26
  • 29
0

Good way is to interrupt() threads, and inside thread make cycle like

try {
   while (!Thread.interrupted()) {
       ...
   }
} catch (InterruptedException e) {
   // if interrupted in sleep
}

Keep in mind both cases when do interrupt:

  • if you sleep or wait then InterruptedException will be thrown;
  • in other cases interrupted flag will be set for the thread which you have to check yourself.
Sergey Aslanov
  • 2,397
  • 15
  • 16
0

The other best approach would be to use interrupt( ) method.

E.g Here's how a thread uses this information to determine whether or not it should terminate :

public class TestAgain extends Thread {
           //  ...
           //  ...
         public void run( ) {
               while (!isInterrupted( )) {
                  //    ...
                     }
                 }     
           }
Saurabh Gokhale
  • 53,625
  • 36
  • 139
  • 164
0

To have a pool of threads I would use the ExecutorService or a ScheduledExecutorService for delayed/periodic tasks.

When you want the workers to stop you can use

executorService.shutdown();
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130