This class uses the {@link ScheduledExecutorService} returned from {@link #executor} to runthe {@link #startUp} and {@link #shutDown} methods and also uses that service to schedule the {@link #runOneIteration} that will be executed periodically as specified by its {@link Scheduler}. When this service is asked to stop via {@link #stop} or {@link #stopAndWait}, it will cancel the periodic task (but not interrupt it) and wait for it to stop before running the {@link #shutDown} method.
Subclasses are guaranteed that the life cycle methods ( {@link #runOneIteration}, {@link #startUp} and {@link #shutDown}) will never run concurrently. Notably, if any execution of {@link #runOneIteration} takes longer than its schedule defines, then subsequent executions may start late. Also, all life cycle methods are executed with a lock held, so subclasses can safely modify shared state without additional synchronization necessary for visibility to later executions of the life cycle methods.
Here is a sketch of a service which crawls a website and uses the scheduling capabilities to rate limit itself.
{@code}class CrawlingService extends AbstractScheduledService private Setvisited; private Queue toCrawl; protected void startUp() throws Exception { toCrawl = readStartingUris(); } protected void runOneIteration() throws Exception { Uri uri = toCrawl.remove(); Collection newUris = crawl(uri); visited.add(uri); for (Uri newUri : newUris) { if (!visited.contains(newUri)) { toCrawl.add(newUri); } } } protected void shutDown() throws Exception { saveUris(toCrawl); } protected Scheduler scheduler() { return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS); } }}
This class uses the life cycle methods to read in a list of starting URIs and save the set of outstanding URIs when shutting down. Also, it takes advantage of the scheduling functionality to rate limit the number of queries we perform. @author Luke Sandberg @since 11.0
|
|
|
|