Re: Multi-threading: wait for tasks to complete
In article <hg4fjb$r67$1@news.eternal-september.org>,
markspace <nospam@nowhere.com> wrote:
Hi all.
I was toying around with some multithreading code today. I ran into a
stick problem: how to wait for an unknown number of tasks to complete.
There seem to be a lot of Java classes that wait for a specific number
of threads or tasks: Semaphore and CountDownLatch, for example. But
there don't seem to be any that allow their value to be changed on the
fly to account for new tasks being created.
Maybe I missed an existing class?
Anyway, the solution I came up with was to roll my own latch, the
UpDownLatch. So named because it can count both up (for new tasks being
spawned) and down (for when the task completes).
Here's the code. Comments welcome. Obviously, it's currently a nested
class; that should be changed for general use.
private static class UpDownLatch
{
private int count;
public synchronized void countUp() {
count++;
}
public synchronized void countDown() {
count--;
if( count == 0 ) {
notifyAll();
}
}
public synchronized void await() throws InterruptedException {
while( count != 0 ) {
wait();
}
}
}
That code is fine. The use can be tricky.
Any thread starting another thread must issue countUp() for that new
thread immediately, or at least before calling countDown() for itself.
Thread.start() can cause run() to execute before start() completes, or
maybe run() happens later. It varies by OS and JVM version.
When looking at the implementation, it appears that it might be best to
move the synchronization. You want to make sure that the threads and
counter always match, even if there are code mistakes. If you're 100%
sure that Thread.start() will never throw, it's safe to take it out of
the synchronized block.
public void start ()
{
synchronized(latch)//Block zero test check until after countUp()
{
super.start(); //May throw IllegalThreadStateException
latch.countUp(); //Only here if it worked
}
}
public void run ()
{
try
{
...code or super.run()
}
finally
{
synchronized(latch)
{
latch.countDown(); //Do this before thread exits.
}
}
}
--
I won't see Goolge Groups replies because I must filter them as spam