开发者

How to Thread.join() on all elements of a list of changing size?

Lets say I have a large number of worker threads all actively processing, and a supervisor thread that waits for them all to complete. Traditionally I could do something like:

for(Worker w:staff){
    w.start();
}
for(Worker w:staff){
    w.join();
}

..and all would be well. However in this case the size of my worker list (ArrayList staff) is variable and may change at arbitrary times. My best knowledge tells me something like this should work:

synchronized(this){
    for(Worker w:staff){
        w.start();
    }
}
while(true){ //this loop will keep the supervisor running until all workers have stopped
                  //interrupts will occur when changes to the size of staff list occur
    try{
        Iterator<Worker> it;
        synchronized(this){
            it = staff.iterator();
        }
        while(it.hasNext()){
            Worker w = it.next();
            w.join();
        }
        return;
    }catch(InterruptedException ie){continue;}
}

This however, still results in a conncurrentModificationException on the line

Worker w = it.next();

...which to me seems strange, because I thought that once you retrieved the iterator it was separ开发者_Python百科ate from the list itself. My next idea is to clone the iterator or staff list so that it IS separate from the original changing list, but I thought I would give you experts a shot at it first.


An Iterator instance is invalidated if any changes are made to the underlying collection outside of the Iterator instance.

Why don't you consider using an ExecutorService instead? Make Worker implement Callable, then use one of the service's invokeAll() methods.

CyclicBarrier or CountDownLatch are lower-level tools that can be used to build similar function.


You get a ConcurrentModificationException when you try to modify a list while an Iterator is partially complete however in your code samples there is no code which adds or removes from the list therefore the problem is elsewhere in your code.

Basically don't remove or add from the list while you are using an Interator, you can remove items using Iterator.remove() instead of List.remove() if you have to remove.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜