Import Java.util.Vector;
Import java.net.*;
Import java.io.*;
public class ThreadPool {
public static final int max_threads = 100;
public static final int max_spare_threads = 50;
public static final int min_spare_threads = 10;
public static final int work_wait_timeout = 60 * 1000;
protected Vector Pool; Storing Idle threads
protected monitorrunnable Monitor; A Monitor thread that monitors the pool for Idel threads.
protected int maxthreads; Max number of threads that you can open in the pool.
protected int minsparethreads; Min number of Idel threads that you can leave in the pool.
protected int maxsparethreads; Max number of Idel threads that you can leave in the pool.
protected int currentthreadcount; Number of threads in the pool.
protected int currentthreadsbusy; Number of busy threads in the pool.
protected Boolean Stopthepool; Flag the pool should terminate all the threads and stop.
/**
* Construct
*/
Public ThreadPool () {
MaxThreads = max_threads;
Maxsparethreads = max_spare_threads;
Minsparethreads = min_spare_threads;
Currentthreadcount = 0;
currentthreadsbusy = 0;
Stopthepool = false;
}
/**
* Start thread pool
*/
Public synchronized void Start () {
Adjustlimits (); Adjusts the maximum and minimum number of threads and the maximum and minimum number of redundant threads.
Openthreads (minsparethreads); Open the initial thread
Monitor = new Monitorrunnable (this); Runnable object Instance//a monitor thread that monitors the pool for Idel threads.
}
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;
}
/**
* Thread pooling Management method.
* Increase the number of processing (idle) threads when there are no idle threads in the idle queue thread.
* If the number of threads has reached the maximum number of threads, the new connection is waiting.
* Call the processing thread for specific business processing when the request arrives and there is an idle thread.
* @param r threadpoolrunnable
*/
The public void Runit (Socket cs) {//R is called when task//tasks are entered
if (Null = CS) {
throw new NullPointerException ();
}
if (0 = = Currentthreadcount | | stopthepool) {
throw new IllegalStateException ();
}
Controlrunnable c = null; Task processing instance.
Synchronized (this) {
if (currentthreadsbusy = = Currentthreadcount) {//If the worker thread is equal to the current number of threads, there is no idle thread.
if (Currentthreadcount < MaxThreads) {//If the current number of threads has not reached the maximum number of threads.
int toopen = Currentthreadcount + minsparethreads; Then increase the amount of minsparethreads threads.
Openthreads (Toopen); Open thread new idle thread. Increased number of Currentthreadcount
}
else {//If the current quantity reaches the maximum number of threads.
while (currentthreadsbusy = = Currentthreadcount) {//When the worker thread is equal to the current number of threads, there is no idle thread.
try {
This.wait (); The connection thread waits.
}
catch (Interruptedexception e) {
}
if (0 = = Currentthreadcount | | stopthepool) {
throw new IllegalStateException ();
}
}
}
}
c = (controlrunnable) pool.lastelement (); When there are idle threads, the last thread is removed from the idle thread queue.
Pool.removeelement (c); Deletes the last thread from the idle queue for handling other events.
currentthreadsbusy++; Add 1 to the number of threads handling the event
}
SYSTEM.OUT.PRINTLN ("System calls a Sokcet thread");
C.runit (CS); Call the specific business method, telling it to have data requests to process, wake up the waiting thread.
}
/**
* Close the thread pool
*/
Public synchronized void shutdown () {
if (!stopthepool) {//If the thread pool is not closed, (thread pool off identity is false)
Stopthepool = true;
Monitor.terminate (); Turn off monitoring threads
monitor = NULL;
for (int i = 0; i < (currentthreadcount-currentthreadsbusy); i++) {//close idle thread queue
try {
((controlrunnable) (Pool.elementat (i))). terminate ();
}
catch (Throwable t) {
}
}
Currentthreadsbusy = Currentthreadcount = 0;
Pool = null;
Notifyall (); Wake up all threads waiting.
}
}
/**
* Close redundant threads when the thread is larger than the maximum redundant thread.
*/
protected synchronized void Checksparecontrollers () {
if (Stopthepool) {//If the connection pool is not closed.
Return
}
if ((currentthreadcount-currentthreadsbusy) > Maxsparethreads) {//If the number of idle threads is greater than the excess maximum number of threads.
int tofree = currentthreadcount-currentthreadsbusy-maxsparethreads; The number of extra threads is drawn
for (int i = 0; i < Tofree i++) {//close delete idle thread, remove from vector
Controlrunnable C = (controlrunnable) pool.firstelement ();
Pool.removeelement (c);
C.terminate (); Let the deleted thread end
currentthreadcount--; Processing thread queues reduces a
}
}
}
/**
* Reset to the idle thread queue when the thread processing is complete.
* @param c controlrunnable
*/
protected synchronized void Returncontroller (controlrunnable c) {
if (0 = = Currentthreadcount | | stopthepool) {//If the thread pool is closed or the current number of connected threads is 0
C.terminate (); Closes the current thread.
Return
}
currentthreadsbusy--; The number of processing thread queues is reduced by one
Pool.addelement (c); Add one in the idle thread queue
Notifyall (); Wakes a thread that may be waiting for a connection.
}
/**
* When an exception occurs for a processing thread, reopen an empty closed thread. And wake up the thread waiting for the idle thread. The thread waiting in the ThreadPool runit.
*/
protected synchronized void Notifythreadend () {
currentthreadsbusy--; The number of thread queues to be processed is reduced by an exception that occurs when the thread is processing data.
currentthreadcount--; The thread with an exception has been closed. The number of threads to be opened is reduced by one.
Notifyall (); Wakes up a blocking thread waiting for a connection.
Openthreads (minsparethreads); Reopen the minsparethreads thread. If the number of Currentthreadcount is greater than minsparethreads, the new thread is not opened.
}
/**
* Adjust the number of thread queues
*/
protected void Adjustlimits () {
if (maxthreads <= 0) {//If the maximum number of threads is less than 0
MaxThreads = max_threads; Set maximum number of threads to 100
}
if (maxsparethreads >= maxthreads) {//If the maximum number of redundant threads is greater than the maximum number of threads.
Maxsparethreads = MaxThreads; Set the maximum number of extra threads to the maximum number of threads.
}
if (maxsparethreads <= 0) {//If the maximum number of redundant threads is less than 0
if (1 = maxthreads) {
Maxsparethreads = 1; If the maximum number of threads is 1, set the maximum number of redundant threads to 1.
}
else {
Maxsparethreads = MAXTHREADS/2; Set the maximum number of redundant threads to half the maximum number of threads.
}
}
if (Minsparethreads > Maxsparethreads) {//If the minimum redundant thread is greater than the maximum number of redundant threads
Minsparethreads = maxsparethreads; Set the minimum number of redundant threads to the maximum number of extra threads.
}
if (minsparethreads <= 0) {//If the minimum number of redundant threads is less than 0
if (1 = maxsparethreads) {
Minsparethreads = 1; If the maximum number of threads is 1, set the minimum number of redundant threads to 1.
}
else {
Minsparethreads = MAXSPARETHREADS/2; Otherwise, set the minimum number of redundant threads to half the maximum number of redundant threads.
}
}
}
/**
* Open a specified number of free thread queues
* @param Toopen int
*/
protected void openthreads (int toopen) {//toopen=minsparethreads
if (Toopen > MaxThreads) {
Toopen = MaxThreads;
}
if (0 = currentthreadcount) {//If the number of threads in the current thread pool is 0
Pool = new Vector (Toopen); Create a vector with a minsparethreads number
}
The first increase in the thread cannot be repeated as a result of the second increase. To start from the Currentthreadcount.
for (int i = Currentthreadcount i < Toopen i++) {//increase minsparethreads number of threads first.
Pool.addelement (This) (new controlrunnable); Runnable instance object that can be used to create a thread
}
Currentthreadcount = Toopen;
}
/**
* Monitor threads to listen for whether the current idle thread is greater than the maximum number of redundant threads, or to close redundant threads if present.
*/
Class Monitorrunnable
Implements Runnable {
ThreadPool p;
Thread T;
Boolean shouldterminate;
/**
* Construct
* @param p ThreadPool
*/
Monitorrunnable (ThreadPool p) {
Shouldterminate = false;
THIS.P = p;
t = new Thread (this);
T.start ();
}
public void Run () {
while (true) {
try {
Synchronized (this) {
This.wait (work_wait_timeout);
}
if (shouldterminate) {//If End
Break
}
P.checksparecontrollers (); Check to see if there are any extra threads.
}
catch (Throwable t) {
T.printstacktrace ();
}
}
}
public void Stop () {
This.terminate ();
}
Public synchronized void terminate () {
Shouldterminate = true;
This.notifyall ();
}
}
}