Making main thread wait for an event
I am doing a college assignment(to be frank enough). The problem is that I should have 4 client threads running at any time (uptil a number n). So, whenver any thread terminates, a new thread must be spawned.
public static void main(String[] args) throws IOException,InterruptedException
{
/* some declarations.. */
ClientThread client=new ClientThread ();
Runnable intr =client;
for(count=1;count<=number;count++)
{
/* If 4 client threads has been spawned, wait until 1 of them exits */
while(Thread.activeCount()<5)
;
new Thread(intr).start();
}
/* Wait until all other threads exits. */
while(Thread.activeCount()!=1)
;
System.out.println("\n The sum of factorials is: "+client.getResult());
}
I want to remove the busy-waitin开发者_如何学Pythong as it defeats the very purpose of my program. How can i make the main thread wait
?? (It shows wait
is a nonstatic method and cannot be invoked from a static method.) Please help.
java.util.concurrent.CountDownLatch is designed for your case.
Define CountDownLatch doneSignal = new CountDownLatch(4);
doneSignal.await()
will wait until doneSignal.countDown()
is called four times.
So let ClientThreads hold sames reference doneSignal
, when run()
exits, call doneSignal.countDown()
.
class ClientThread implements Runnable {
private final CountDownLatch doneSignal;
ClientThread (CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
public void run() {
try {
//Do something
doneSignal.countDown();
} catch (InterruptedException ex) {}
}
}
...
//In main thread
doneSignal.await();
Hmm - do you have to do it by hand or does your teacher expect that you discover Executors.newFixedThreadPool(4)
?
That's exactly what a thread pool with four worker threads would do: no more then four clients run in parallel, if one terminates, the free'd worker thread is ready to "get a new job".
It's pretty simple:
public void test(int threads, int runnables) {
ExecutorsService pool = Executors.newFixedThreadPool(threads);
Runnable r = new Runnable() {
public void run() {
// calculate a factorial or do something else
System.out.println(Thread.currenThread());
}
}
for (int i = 0; i < runnables; i++)
pool.execute(r);
}
Let runnables
be bigger then threads
and you'll see from the result that at most threads
number of threads are (re-)used to execute the runnables.
You can write a callback method in your main class, that is called by an exiting thread and spawns a new one. By using a static field in the main class you will keep track of the number of threads spawned to obtain the same effect as the current code.
it would look somehow like this :
class Main{
private static ClientThread client;
private static Runnable intr;
private static int count;
public static void main(String[] args)
{
count = 10; //Or something else
runningThreads = 0;
client=new ClientThread ();
intr =client;
for(i=0;i<5;i++)
spawnThread();
}
private static void spawnThread()
{
Thread newThread;
if(count>0)
{
newThread = new Thread(intr);
newThread.start();
count--;
}
if(count==0)
System.out.println("\n The sum of factorials is: "+client.getResult());
}
Take a look @ classes in java.util.concurrent Specifically java.util.concurrent.CountDownLatch java.util.concurrent.locks.Condition
For the main thread you can use:
Thread.getCurrent().join();
This will wait for all the spawned threads to die, before the main thread terminates.
精彩评论