Couldn't you use the built in thread pool functionality?
If not, the problem is that runningThreads
doesn't get increased until each thread starts and has acquired the lock. In practice the main thread may run for quite some time, all the while spinning up new threads without limit.
One solution might be to increase the runningThreads
variable on the main thread, just before starting the new thread, but leave decreasing the variable inside each of the worker threads.
I don't want to suggest that everything else about your code is "good" (creating a robust thread-pool implementation can be quite a difficult and involved task) but a minimal change that may avoid the problem could be
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public static void main(String[] args) {
//overcome limitation of closure not being able to modify outer variable with arr.
final int[] runningThreads = {0};
final int[] taskcount = {10};
final Lock _mutex = new ReentrantLock(true);
int maxThreadQty = 3;
while ((taskcount[0] > 0) && (runningThreads[0] < maxThreadQty)) {
System.out.println("New Thread Started");
_mutex.lock();
runningThreads[0]++;
System.out.println("Running Threads: " + runningThreads[0]);
System.out.println("Times to go: " + taskcount[0]);
_mutex.unlock();
new Thread("T") {
public void run() {
// actually do something;
_mutex.lock();
taskcount[0]--;
runningThreads[0]--;
_mutex.unlock();
}
}.start();
}
}
}