- A Somewhat Complex Example
- Starting and Stopping
- Spectators
- Timing, Scoring, and Spectating
- Startup and Shutdown
- Wrap Up
Startup and Shutdown
We've already seen the use of a scheduled ThreadPool for the running of our Spectator objects, but that's just scratching the surface of what the new Executor class allows us to do. Executor is an interface that defines a single method, execute(Runnable), but the various implementations enable us to monitor pools of threads and maintain control over their status. Executor instances can be retrieved through the Executors factory, which has static methods for all sorts of concrete implementations of Executor.
For the threads that will monitor the three sector time queues (our SectorIntervalMonitors mentioned earlier), we use a FixedThreadPool to create and hold them, storing instances of Future in an array to keep track of them:
public void setupTiming() { SectorIntervalMonitor intervalMonitor = null; setMonitorFutures(new Future[NUM_SECTORS]); setSectorQueues(new ConcurrentLinkedQueue[NUM_SECTORS]); setSectorMonitorPool(Executors.newFixedThreadPool(NUM_SECTORS)); for(int sector = 0; sector < NUM_SECTORS; ++sector) { //Create sector queue getSectorQueues()[sector] = new ConcurrentLinkedQueue<SectorTime>(); //Create sector interval monitors intervalMonitor = new SectorIntervalMonitor("Sector " + sector, getSectorQueues()[sector], this, getEvent().getGreenFlag(), getEvent().getCheckeredFlag()); getMonitorFutures()[sector] = getSectorMonitorPool().submit(intervalMonitor); } }
And here's a method that will block until all the SectorIntervalMonitors have been completed (which happens when all the cars have crossed the finish line and all their times have been processed):
public void awaitTrackShutdown() { boolean stillWorking = false; //Wait for monitors to finish while(true) { stillWorking = false; for(int future = 0; future < getMonitorFutures().length; ++future) { if(!getMonitorFutures()[future].isDone()) { stillWorking = true; break; } } if(stillWorking) { try { Thread.sleep(50); } catch(Exception e){} } else { break; } } ///Must remember to shut down!!! getSectorMonitorPool().shutdown(); }
The isDone() call returns true when the run() method on its assigned SectorIntervalMonitor completes. Make sure that you explicitly call shutdown() on your ExecutorService; otherwise, your application may never terminateeven after your threads complete!