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    }