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
}
}
}
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();
}
}