// // WKExecutorService.java // cheetah // // Created by Kieran Kelleher on 4/13/06. // Copyright 2006 Kieran Kelleher. All rights reserved. // package er.extensions.concurrency; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; /** * <p> * A simple class that provides a resource-efficient WebObjects-friendly {@link ExecutorService} for a * single application. ExecutorService instances are used for running tasks in asynchronous threads. * Access the shared instance with: * <p> * <pre> * ExecutorService es = ERXExecutorService.executorService(); * </pre> * * <p> * This class also provides a factory method to create a fixed size thread pool ExecutorService * that rejects tasks when all threads are busy. This can be useful for parallel processing * tasks. * </p> * * <p> * Implements custom Thread and ThreadPoolExecutor subclasses that cooperate to * maintain reference to currently executing task while executing and * to ensure locked editing contexts are unlocked at the end of a task. * </p> * * @see ERXTaskThreadPoolExecutor * @see ERXTaskThreadFactory * @see ERXTaskThread * @see ERXExecutorService * */ public class ERXExecutorService { private static final ExecutorService _executorService = new ERXTaskThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ERXTaskThreadFactory()); /** * @return a global ExecutorService with no limit for executing runnables. **/ public static ExecutorService executorService() { return _executorService; } /** * This ExecutorService is useful when you want to execute tasks in parallel, but you want to (create and) * submit new tasks for execution only when the pool has at least one idle thread. * * A task will be rejected with a {@link RejectedExecutionException} when all the threads are busy * running other tasks. * * Thus, you can fill the pool with tasks and use a try/catch/wait loop for submitting additional tasks. * * Idle threads will be terminated if idle for more than 30 seconds. * * @param nThreads * @return a fixed-size thread pool that only accepts tasks when a thread is idle. */ public static ExecutorService newFiniteThreadPool(int nThreads) { return new ERXTaskThreadPoolExecutor( 0, nThreads, 30L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ERXTaskThreadFactory()); } }