Search code examples
javamultithreadingworker-thread

Is it possible to call the main thread from a worker thread in Java?


I have a method called action() that deploys three threads. Each deployed thread or worker thread falls into a while loop based on a single instance variable of type boolean being true, for example boolean doWork = true, each thread will have a while(doWork){} loop.

When a thread finishes the job will set the doWork to false stopping all the threads from looping. Then I would like to be able to somehow let the main thread recall the action() method to redeploy the threads to do another job. (If I use one of the worker threads to call the action() method is it OK ?) will the worker thread terminate once it calls the action() method and somehow die ?

I limited the example to two threads for simplicity

Thanks

class TestThreads{
    boolean doWork = true;

    void action(){
         ThreadOne t1 = new ThreadOne();
         ThreadTwo t2 = new ThreadTwo();
    }

    //innerclasses

    class ThreadOne implements Runnable{
          Thread trd1;
          public ThreadOne(){//constructor
              if(trd1 == null){
                   trd1 = new Thread(this);
                   trd1.start();
              }
          }
          @Override
          public void run(){
              while(doWork){
                   //random condition
                   //would set doWork = false;
                   //stop all other threads
              }
              action();//is the method in the main class
          }
    }
    class ThreadTwo implements Runnable{
          Thread trd2;
          public ThreadTwo(){//constroctor
              if(trd2 == null){
                   trd2 = new Thread(this);
                   trd2.start();
              }
          }
          @Override
          public void run(){
              while(doWork){
                   //random condition
                   //would set doWork = false;
                   //stop all other threads
              }
              action();//is the method in the main class
          }
    }

}

Solution

  • How about this implementation:

    Declare a class member doWork, a counter for currently active threads and a synchronization object:

    private volatile boolean doWork = true;
    private AtomicInteger activeThreads;
    private Object locker = new Object();
    

    In main:

    while(true) {
        // call action to start N threads
        activeThreads = new AtomicInteger(N);
        action(N);
        // barrier to wait for threads to finish
        synchronized(locker) {
           while(activeThreads.get() > 0) {
               locker.wait();
           }
        }
    }
    

    In thread body:

    public void run() {
       while(doWork) {
          ...
          // if task finished set doWork to false
       }
    
       // signal main thread that I've finished
       synchronized(locker) {
          activeThreads.getAndDecrement();
          locker.notify();
       }
    }