Search code examples
javamultithreadingwaitnotify

Stop thread from inside and notify from outside


Here's the basic concept of what I want to do

LEt's say I have thread one that looks like this.

public class Thread1 implements Runnable{

    run(){

        while(true){
       //doWork and have thread 2 start working over a TCP connection, in my particular case
       wait();
   }

}

And thread 2

 public class Thread2 implements Runnable{

    run(){

       while(true){
       //doWork and now I need to wake up thread 1
       t1.notify(); //???
    }

}

This obviously doesn't work... My question is how to make this work basically. Both threads are created in main, so I can give them any information necessary to each other. Any help would be appreciated.


Solution

  • I can think of several schools of thought:

    The first one is to have 2 threads, as in your example. They can share several types of objects through which thread2 can notify thread1.

    Using java.util.concurrent.Condition:

    // thread1
    public void run() {
        // to wait
        lock.lock();
        try {
            condition.await();
        } finally {
            lock.unlock();
        }
    }
    
    //thread2
    public void run() {
        // to notify
        lock.lock();
        try {
            condition.signal();
        } finally {
            lock.unlock();
        }
    }
    

    You can also use CyclicBarrier, and maybe other types.

    The second school of thought is to have a single work thread, which executes the other using ExecutorService:

    // thread2
    public void run() {
        executorService.execute(new RunnableThread1());
    }
    

    This concept looks at the work done by thread1 as a detached task which can be executed multiple times. So this may not be compatible with your program.

    And the last option is to use Thread.interrupt:

    //thread1
    public void run() {
        while (true) {
             try {
                 Thread.sleep(sleepTime);
             } catch(InterruptedException e) {
                 // signaled.
             }
        }
    }
    
    //thread 2
    public void run() {
        thread1.interrupt();
    }
    

    This may be a bit problematic since the interrupt call is better used to stop threads and not to signal them.