Work Sets
 
Support Ukraine

Work Sets

When using the thread pool framework I found that the concept of a "work set" class was very useful. The idea can be summarized as "a set of Callables that you create, add work units to, and then complete()". This is nothing other than an implementation of the Submit and Complete / Fork-and-Join pattern described in the thread pool atricle. The very simple code is included below and while very useful in itself, it really shines when we add a parallel for and a parallel forEach to it. The concept is similar to child tasks in the .Net framework 4[a].

/**
 * Utility class to submit a set of work units and complete them.
 */
public class WorkSet<Result> {
    
    /**
     * The futures corresponding to the callables that
     * have been added to this work set so far.
     */
    private final List<Future<Result>> futures =
        new ArrayList<Future<Result>>();
    
    /**
     * The thread pool to use.
     */
    private final ThreadPool threadPool;
    
    /**
     * Creates a new work set with in ThreadPool.getDefault ().
     */
    public WorkSet () {
        this (ThreadPool.getDefault ());
    }
    
    /**
     * Creates a new work set with the given default thread class.
     */
    public WorkSet (ThreadPool threadPool) {
        this.threadPool = threadPool;
    }
    
    /**
     * Executes a callable.
     */
    public void execute (Callable<Result> callable) {
        futures.add (threadPool.execute (callable));
    }
    
    /**
     * Completes all futures.
     */
    public List<Future<Result>> complete () throws Exception {
        threadPool.complete (futures);
        return futures;
    }
    
    /**
     * Completes all futures and retrieves all results.
     */
    public List<Result> join () throws Exception {
        List<Result> res = new ArrayList<Result> ();
        for (Future<Result> f : complete ()) {
            res.add (f.get ());
        }
        return res;
    }
}