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 }