import edu.mit.media.hive.support.Debug; import java.io.*; public class WorkerPool { static QueryServer[] pool; int lastIdle = -1; public WorkerPool(int size) { pool = new QueryServer[size]; } public void createWorkers(NTPSpider spider) { for (int i = 0; i < pool.length; i++) { QueryServer qs = new QueryServer(this, spider); Thread t = new Thread(qs); t.setDaemon(true); t.start(); addWorker(qs); } } /** Schedule a job. Block if the whole pool is busy. **/ public void doJob(String host) { QueryServer qs = getWorker(); qs.processHost(host); } /** Are all threads busy? **/ private synchronized boolean allBusy() { // All threads busy of there are no idles. return lastIdle < 0; } /** Wait until all threads done **/ public synchronized void waitForAllDone() { while (lastIdle < pool.length - 1) { try { wait(); } catch (InterruptedException ex) { } } } /** Call this to add a worker to the pool. Typically called by ** the worker itself when it finishes its job. **/ public synchronized void addWorker(QueryServer qs) { // put this worker back on the pool pool[lastIdle+1] = qs; lastIdle++; // tell anyone waiting on the pool to fill notify(); } /** Get a worker from the thread. Block if all are busy. **/ private synchronized QueryServer getWorker() { while (allBusy()) { try { wait(); } catch (InterruptedException ex) { } } QueryServer qs = pool[lastIdle]; lastIdle--; return qs; } public static void main(String args[]) { if (args.length < 2) { System.out.println("Usage: WorkerPool NumThreads CommandFile"); System.exit(1); } int poolSize = 1; BufferedReader br = null; try { poolSize = Integer.parseInt(args[0]); br = new BufferedReader(new FileReader(args[1])); } catch (Exception ex) { Debug.error(ex); } WorkerPool wp = new WorkerPool(poolSize); String job; try { while ((job = br.readLine()) != null) wp.doJob(job); } catch (IOException ex) { Debug.error(ex); } wp.waitForAllDone(); Debug.notice("All jobs finished."); } }