⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 threadpool.java

📁 Tomcat 4.1与WebServer集成组件的源代码包.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, if *    any, must include the following acknowlegement: *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowlegement may appear in the software itself, *    if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software *    Foundation" must not be used to endorse or promote products derived *    from this software without prior written permission. For written *    permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" *    nor may "Apache" appear in their names without prior written *    permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */package org.apache.tomcat.util.threads;import java.util.*;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;/** * A thread pool that is trying to copy the apache process management. * * @author Gal Shachor */public class ThreadPool  {    static Log log = LogFactory.getLog(ThreadPool.class);    /*     * Default values ...     */    public static final int MAX_THREADS = 200;    public static final int MAX_SPARE_THREADS = 50;    public static final int MIN_SPARE_THREADS = 4;    public static final int WORK_WAIT_TIMEOUT = 60*1000;    /*     * Where the threads are held.     */    protected ControlRunnable[] pool = null;    /*     * A monitor thread that monitors the pool for idel threads.     */    protected MonitorRunnable monitor;    /*     * Max number of threads that you can open in the pool.     */    protected int maxThreads;    /*     * Min number of idel threads that you can leave in the pool.     */    protected int minSpareThreads;    /*     * Max number of idel threads that you can leave in the pool.     */    protected int maxSpareThreads;    /*     * Number of threads in the pool.     */    protected int currentThreadCount;    /*     * Number of busy threads in the pool.     */    protected int currentThreadsBusy;    /*     * Flag that the pool should terminate all the threads and stop.     */    protected boolean stopThePool;    /* Flag to control if the main thread is 'daemon' */    protected boolean isDaemon=true;    /** The threads that are part of the pool.     * Key is Thread, value is the ControlRunnable     */    protected Hashtable threads=new Hashtable();    protected Vector listeners=new Vector();    /** Name of the threadpool     */    protected String name=null;    /**     * Helper object for logging     **/    //Log loghelper = Log.getLog("tc/ThreadPool", "ThreadPool");        public ThreadPool() {        maxThreads      = MAX_THREADS;        maxSpareThreads = MAX_SPARE_THREADS;        minSpareThreads = MIN_SPARE_THREADS;        currentThreadCount  = 0;        currentThreadsBusy  = 0;        stopThePool = false;    }    /** Create a ThreadPool instance.     *     * @param jmx True if you want a pool with JMX support. A regular pool     *  will be returned if JMX or the modeler are not available.     *     * @return ThreadPool instance. If JMX support is requested, you need to     *   call register() in order to set a name.     */    public static ThreadPool createThreadPool(boolean jmx) {        return new ThreadPool();    }    public void register( String domain, String name ) {        // nothing in the base class - it'll register in jmx mode        // We could use the name to create a ThreadGroup and name threads    }    public synchronized void start() {	stopThePool=false;        currentThreadCount  = 0;        currentThreadsBusy  = 0;        adjustLimits();        pool = new ControlRunnable[maxThreads];        openThreads(minSpareThreads);        monitor = new MonitorRunnable(this);    }    public MonitorRunnable getMonitor() {        return monitor;    }    public void setMaxThreads(int maxThreads) {        this.maxThreads = maxThreads;    }    public int getMaxThreads() {        return maxThreads;    }    public void setMinSpareThreads(int minSpareThreads) {        this.minSpareThreads = minSpareThreads;    }    public int getMinSpareThreads() {        return minSpareThreads;    }    public void setMaxSpareThreads(int maxSpareThreads) {        this.maxSpareThreads = maxSpareThreads;    }    public int getMaxSpareThreads() {        return maxSpareThreads;    }    public int getCurrentThreadCount() {        return currentThreadCount;    }    public int getCurrentThreadsBusy() {        return currentThreadsBusy;    }    public boolean isDaemon() {        return isDaemon;    }    public static int getDebug() {        return 0;    }    /** The default is true - the created threads will be     *  in daemon mode. If set to false, the control thread     *  will not be daemon - and will keep the process alive.     */    public void setDaemon( boolean b ) {        isDaemon=b;    }        public boolean getDaemon() {        return isDaemon;    }    public void addThread( Thread t, ControlRunnable cr ) {        threads.put( t, cr );        for( int i=0; i<listeners.size(); i++ ) {            ThreadPoolListener tpl=(ThreadPoolListener)listeners.elementAt(i);            tpl.threadStart(this, t);        }    }    public void removeThread( Thread t ) {        threads.remove(t);        for( int i=0; i<listeners.size(); i++ ) {            ThreadPoolListener tpl=(ThreadPoolListener)listeners.elementAt(i);            tpl.threadEnd(this, t);        }    }    public void addThreadPoolListener( ThreadPoolListener tpl ) {        listeners.addElement( tpl );    }    public Enumeration getThreads(){        return threads.keys();    }    //    // You may wonder what you see here ... basically I am trying    // to maintain a stack of threads. This way locality in time    // is kept and there is a better chance to find residues of the    // thread in memory next time it runs.    //    /**     * Executes a given Runnable on a thread in the pool, block if needed.     */    public void runIt(ThreadPoolRunnable r) {        if(null == r) {            throw new NullPointerException();        }        if(0 == currentThreadCount || stopThePool) {            throw new IllegalStateException();        }        ControlRunnable c = null;        // Obtain a free thread from the pool.        synchronized(this) {            if(currentThreadsBusy == currentThreadCount) {                 // All threads are busy                if(currentThreadCount < maxThreads) {                    // Not all threads were open,                    // Open new threads up to the max number of idel threads                    int toOpen = currentThreadCount + minSpareThreads;                    openThreads(toOpen);                } else {		    logFull(log, currentThreadCount, maxThreads);                    // Wait for a thread to become idel.                    while(currentThreadsBusy == currentThreadCount) {                        try {                            this.wait();                        }			// was just catch Throwable -- but no other			// exceptions can be thrown by wait, right?			// So we catch and ignore this one, since			// it'll never actually happen, since nowhere			// do we say pool.interrupt().			catch(InterruptedException e) {			    log.error("Unexpected exception", e);                        }                        // Pool was stopped. Get away of the pool.                        if(0 == currentThreadCount || stopThePool) {                            throw new IllegalStateException();                        }                    }                }            }            // If we are here it means that there is a free thread. Take it.            c = pool[currentThreadCount - currentThreadsBusy - 1];            currentThreadsBusy++;        }        c.runIt(r);    }    static boolean logfull=true;    public static void logFull(Log loghelper, int currentThreadCount, int maxThreads) {	if( logfull ) {            log.error("All threads are busy, waiting. Please " +                    "increase maxThreads or check the servlet" +                    " status" + currentThreadCount + " " +                    maxThreads  );	    logfull=false;	}     }    /**     * Stop the thread pool     */    public synchronized void shutdown() {        if(!stopThePool) {            stopThePool = true;            monitor.terminate();            monitor = null;            for(int i = 0 ; i < (currentThreadCount - currentThreadsBusy - 1) ; i++) {                try {                    pool[i].terminate();                } catch(Throwable t) {                    /*		     * Do nothing... The show must go on, we are shutting

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -