/* * Generic example of master/worker program with dynamic assignment of * tasks to workers. (The point of this example is to demonstrate use * of tags.) "Tasks" just consist of sleeping for a specified * time; times to wait are generatedly randomly from 0 to a specified * maximum. * * Command-line arguments: total tasks, maximum wait time, number of threads */ public class MasterWorker { /* variables/constants to be used by all threads */ private static int totalTasks; private static int maxWait; private static int nThreads; private static int minCount = -1; private static int maxCount = -1; private static int minTime = -1; private static int maxTime = -1; private static java.util.Random randGenerator = new java.util.Random(); private static int tasksAssigned = 0; /* main method (also serves as master) */ public static void main(String[] args) { /* process command-line argument */ if (args.length < 3) { System.err.println("usage: MasterWorker totalTasks maxWait nThreads"); System.exit(1); } try { totalTasks = Integer.parseInt(args[0]); maxWait = Integer.parseInt(args[1]); nThreads = Integer.parseInt(args[2]); } catch (NumberFormatException e) { System.err.println("usage: MasterWorker totalTasks maxWait nThreads"); System.exit(1); } /* start timing */ long startTime = System.currentTimeMillis(); /* create threads */ Thread[] threads = new Thread[nThreads]; for (int i = 0; i < threads.length; ++i) { threads[i] = new Thread(new CodeForThread(i)); } /* start them up */ for (int i = 0; i < threads.length; ++i) { threads[i].start(); } /* wait for them to finish */ for (int i = 0; i < threads.length; ++i) { try { threads[i].join(); } catch (InterruptedException e) { System.err.println("this should not happen"); } } /* print results */ System.out.println("task count ranged from " + minCount + " to " + maxCount); System.out.println("time ranged from " + minTime + " to " + maxTime); } /* method to "get something from the bag of tasks" -- returns -1 * when no more to get */ private static synchronized int getTask() { if (++tasksAssigned <= totalTasks) return randGenerator.nextInt(maxWait); else return -1; } /* method to update min, max counts */ private static synchronized void updateMinMax(int workerCount, int workerTime) { if ((workerCount < minCount) || (minCount < 0)) minCount = workerCount; if (workerCount > maxCount) maxCount = workerCount; if ((workerTime < minTime) || (minTime < 0)) minTime = workerTime; if (workerTime > maxTime) maxTime = workerTime; } /* static inner class to contain code to run in each thread */ private static class CodeForThread implements Runnable { private int myID; public CodeForThread(int myID) { this.myID = myID; } public void run() { int taskCount = 0; int totalWorkTime = 0; int workAmount = 0; while ((workAmount = getTask()) >= 0) { System.out.println("worker " + myID + " received " + workAmount); ++taskCount; totalWorkTime += workAmount; try { Thread.sleep(workAmount); } catch (InterruptedException e) { System.err.println("this should not happen"); } } System.out.println("worder " + myID + " done"); updateMinMax(taskCount, totalWorkTime); } } }