diff options
Diffstat (limited to 'simple/simple-common/src/main/java/org/simpleframework/common/thread/ExecutorQueue.java')
-rw-r--r-- | simple/simple-common/src/main/java/org/simpleframework/common/thread/ExecutorQueue.java | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/simple/simple-common/src/main/java/org/simpleframework/common/thread/ExecutorQueue.java b/simple/simple-common/src/main/java/org/simpleframework/common/thread/ExecutorQueue.java new file mode 100644 index 0000000..99e8fb2 --- /dev/null +++ b/simple/simple-common/src/main/java/org/simpleframework/common/thread/ExecutorQueue.java @@ -0,0 +1,128 @@ +/* + * ExecutorQueue.java February 2007 + * + * Copyright (C) 2007, Niall Gallagher <niallg@users.sf.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package org.simpleframework.common.thread; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * The <code>ExecutorQueue</code> object is used to queue tasks in + * a thread pool. This creates a thread pool with no limit to the + * number of tasks that can be enqueued, which ensures that any + * system requesting a task to be executed will not block when + * handing it over, it also means the user must use caution. + * + * @author Niall Gallagher + * + * @see org.simpleframework.common.thread.ConcurrentExecutor + */ +class ExecutorQueue { + + /** + * This is the task queue that contains tasks due to execute. + */ + private final BlockingQueue<Runnable> queue; + + /** + * This is the actual thread pool implementation used. + */ + private final ThreadPoolExecutor executor; + + /** + * This is used to create the pool worker threads. + */ + private final ThreadFactory factory; + + /** + * Constructor for the <code>ExecutorQueue</code> object. This is + * used to create a pool of threads that can be used to execute + * arbitrary <code>Runnable</code> tasks. If the threads are + * busy this will simply enqueue the tasks and return. + * + * @param type this is the type of runnable that this accepts + * @param rest this is the number of threads to use in the pool + * @param active this is the maximum size the pool can grow to + */ + public ExecutorQueue(Class type, int rest, int active) { + this(type, rest, active, 120, TimeUnit.SECONDS); + } + + /** + * Constructor for the <code>ExecutorQueue</code> object. This is + * used to create a pool of threads that can be used to execute + * arbitrary <code>Runnable</code> tasks. If the threads are + * busy this will simply enqueue the tasks and return. + * + * @param type this is the type of runnable that this accepts + * @param rest this is the number of threads to use in the pool + * @param active this is the maximum size the pool can grow to + * @param duration the duration active threads remain idle for + * @param unit this is the time unit used for the duration + */ + public ExecutorQueue(Class type, int rest, int active, long duration, TimeUnit unit) { + this.queue = new LinkedBlockingQueue<Runnable>(); + this.factory = new DaemonFactory(type); + this.executor = new ThreadPoolExecutor(rest, active, duration, unit, queue, factory); + } + + /** + * The <code>execute</code> method is used to queue the task for + * execution. If all threads are busy the provided task is queued + * and waits until all current and outstanding tasks are finished. + * + * @param task this is the task to be queued for execution + */ + public void execute(Runnable task) { + executor.execute(task); + } + + /** + * This is used to stop the executor by interrupting all running + * tasks and shutting down the threads within the pool. This will + * return once it has been stopped, and no further tasks will be + * accepted by this pool for execution. + */ + public void stop() { + stop(60000); + } + + /** + * This is used to stop the executor by interrupting all running + * tasks and shutting down the threads within the pool. This will + * return once it has been stopped, and no further tasks will be + * accepted by this pool for execution. + * + * @param wait the number of milliseconds to wait for it to stop + */ + public void stop(long wait) { + if(!executor.isTerminated()) { + try { + executor.shutdown(); + executor.awaitTermination(wait, MILLISECONDS); + } catch(Exception e) { + throw new IllegalStateException("Could not stop pool", e); + } + } + } +} |