001    package com.hammurapi.util.concurrent;
002    
003    /**
004     * This class increments counter when created and 
005     * decrements when run() method exits. When counter reaches zero, this
006     * class invokes notifyAll() on the counter. The class shall be used for 
007     * parallel execution of tasks when it is required to wait until all tasks
008     * complete.
009     * @author Pavel Vlasov
010     *
011     */
012    public class CountedRunnable implements Runnable {
013            
014            /**
015             * Counter to use with CounterRunnable.
016             * @author Pavel Vlasov
017             */
018            public static class Counter {
019                    private int counter;
020                    
021                    synchronized void inc() {
022                            ++counter;
023                    }
024                    
025                    synchronized void dec() {
026                            if (--counter <= 0) {
027                                    notifyAll();
028                            }
029                    }
030                    
031                    public synchronized void join() throws InterruptedException {
032                            while (counter>0) {
033                                    wait();
034                            }
035                    }
036            }
037            
038            private Counter counter;
039            private Runnable master;
040    
041            public CountedRunnable(Counter counter, Runnable master) {
042                    this.counter = counter;
043                    counter.inc();
044                    this.master = master;
045            }
046    
047            final public void run() {
048                    try {
049                            master.run();
050                    } finally {
051                            counter.dec();
052                    }
053            }
054    
055    }