001 /*
002 * Copyright 1999-2004 The Apache Software Foundation.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.apache.commons.threadpool;
017
018 /**
019 * A default implementation of a ThreadPool
020 * which is constructed with a given number of threads.
021 *
022 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
023 * @version $Revision: 155472 $
024 */
025 public class DefaultThreadPool implements Runnable, ThreadPool {
026
027 private MTQueue queue = new MTQueue();
028 private boolean stopped = false;
029 private final ThreadPoolMonitor monitor;
030 private ThreadGroup threadGroup;
031
032 public DefaultThreadPool(ThreadPoolMonitor monitor,
033 int numberOfThreads, int threadPriority) {
034 this.monitor = monitor;
035 for ( int i = 0; i < numberOfThreads; i++ ) {
036 startThread(threadPriority);
037 }
038 }
039
040 public DefaultThreadPool(ThreadPoolMonitor monitor,
041 int numberOfThreads) {
042 this.monitor = monitor;
043 for ( int i = 0; i < numberOfThreads; i++ ) {
044 startThread();
045 }
046 }
047
048 public DefaultThreadPool() {
049 this.monitor = new CommonsLoggingThreadPoolMonitor();
050 // typically a thread pool should have at least 1 thread
051 startThread();
052 }
053
054 public DefaultThreadPool(int numberOfThreads) {
055 this(new CommonsLoggingThreadPoolMonitor(), numberOfThreads);
056 }
057
058 public DefaultThreadPool(int numberOfThreads, int threadPriority) {
059 this(new CommonsLoggingThreadPoolMonitor(), numberOfThreads, threadPriority);
060 }
061
062 public void setThreadGroup(ThreadGroup threadGroup) {
063 this.threadGroup = threadGroup;
064 }
065
066 /** Start a new thread running */
067 public Thread startThread() {
068 Thread thread = createThread();
069 thread.start();
070 return thread;
071 }
072
073 public Thread startThread(int priority) {
074 Thread thread = createThread();
075 thread.setPriority(priority);
076 thread.start();
077 return thread;
078 }
079
080 private Thread createThread() {
081 if(this.threadGroup != null) {
082 return new Thread(this.threadGroup, this);
083 } else {
084 return new Thread(this);
085 }
086 }
087
088 public void stop() {
089 stopped = true;
090 }
091
092 /**
093 * Returns number of runnable object in the queue.
094 */
095 public int getRunnableCount() {
096 return queue.size();
097 }
098
099
100 // ThreadPool interface
101 //-------------------------------------------------------------------------
102
103 /**
104 * Dispatch a new task onto this pool
105 * to be invoked asynchronously later
106 */
107 public void invokeLater(Runnable task) {
108 queue.add( task );
109 }
110
111 // Runnable interface
112 //-------------------------------------------------------------------------
113
114 /** The method ran by the pool of background threads
115 */
116 public void run() {
117 while ( ! stopped ) {
118 Runnable task = (Runnable) queue.remove();
119 if ( task != null ) {
120 try {
121 task.run();
122 }
123 catch (Throwable t) {
124 monitor.handleThrowable(this.getClass(), task, t);
125 }
126 }
127 }
128 }
129 }