Java伺服器端Socket線程池

來源:互聯網
上載者:User

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; //存放空閑線程
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 that 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;
}
/**
* 啟動線程池
*/
public synchronized void start() {
adjustLimits(); //調整最大和最小線程數及最大和最小多餘線程數.
openThreads(minSpareThreads); //開啟初始線程
monitor = new MonitorRunnable(this); //Runnable對象執行個體 //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;
}
/**
* 線程池管理方法.
* 當空閑隊列線程中沒有空閑線程時,則增加處理(空閑)線程數量.
* 如果線程數量已達到最大線程數,則新的串連進行等待.
* 當請求到來,且有空閑線程時調用處理線程進行具體業務處理.
* @param r ThreadPoolRunnable
*/
public void runIt(Socket cs) { //r 為task //有任務進入時調用
if (null == cs) {
throw new NullPointerException();
}
if (0 == currentThreadCount || stopThePool) {
throw new IllegalStateException();
}
ControlRunnable c = null; //任務處理執行個體.
synchronized (this) {
if (currentThreadsBusy == currentThreadCount) { //如果背景工作執行緒和當前線程數相等,說明沒有空閑線程.
if (currentThreadCount < maxThreads) { //如果當前線程數還沒有達到最大線程數.
int toOpen = currentThreadCount + minSpareThreads; //再增加minSpareThreads個線程量.
openThreads(toOpen); //開啟線程新增空閑線程. //currentThreadCount數量增加
}
else { //如果當前數量達到了最大線程數.
while (currentThreadsBusy == currentThreadCount) { //當背景工作執行緒和當前線程數相等,說明沒有空閑線程.
try {
this.wait(); //連接線程進行等待.
}
catch (InterruptedException e) {
}
if (0 == currentThreadCount || stopThePool) {
throw new IllegalStateException();
}
}
}
}
c = (ControlRunnable) pool.lastElement(); //在有空閑線程的情況下,從空閑線程隊列中取出最後一個線程.
pool.removeElement(c); //從空閑隊列中刪除最後一個線程,用於處理其他事件.
currentThreadsBusy++; //對處理事件的線程數加1
}
System.out.println("系統調用一個Sokcet線程");
c.runIt(cs); //調用具體業務方法,告訴其有資料請求要處理,喚醒等待中的線程.
}
/**
* 關閉線程池
*/
public synchronized void shutdown() {
if (!stopThePool) { //如果線程池沒有關閉,(線程池關閉標識為假)
stopThePool = true;
monitor.terminate(); //關閉監視線程
monitor = null;
for (int i = 0; i < (currentThreadCount - currentThreadsBusy); i++) { //關閉空閑線程隊列
try {
( (ControlRunnable) (pool.elementAt(i))).terminate();
}
catch (Throwable t) {
}
}
currentThreadsBusy = currentThreadCount = 0;
pool = null;
notifyAll(); //喚醒所有在等待的線程.
}
}
/**
* 當線程大於最大多餘線程時關閉多餘的線程.
*/
protected synchronized void checkSpareControllers() {
if (stopThePool) { //如果串連池沒有關閉.
return;
}
if ( (currentThreadCount - currentThreadsBusy) > maxSpareThreads) { //如果閒置線程數大於多餘的最大線程數量.
int toFree = currentThreadCount - currentThreadsBusy - maxSpareThreads; //得出多餘的線程數量
for (int i = 0; i < toFree; i++) { //關閉刪除空閑線程,從Vector中刪除
ControlRunnable c = (ControlRunnable) pool.firstElement();
pool.removeElement(c);
c.terminate(); //讓刪除的線程結束
currentThreadCount--; //處理線程隊列減少一個
}
}
}
/**
* 當線程處理完成後重新放到空閑線程隊列中.
* @param c ControlRunnable
*/
protected synchronized void returnController(ControlRunnable c) {
if (0 == currentThreadCount || stopThePool) { //如果線程池關閉或當前連接線程數量為0
c.terminate(); //關閉當前線程.
return;
}
currentThreadsBusy--; //處理線程隊列的數量減少一個
pool.addElement(c); //空閑線程隊列中增加一個
notifyAll(); //喚醒可能在等待串連的線程.
}
/**
* 當一個處理線程出現異常時,要重新開啟一個空閉線程.,並喚醒在等待空閑線程的線程.ThreadPool的runIt中等待的線程.
*/
protected synchronized void notifyThreadEnd() {
currentThreadsBusy--; //因從線程是在處理資料時出現異常,所處理線程隊列的數量要減一個.
currentThreadCount--; //因出現異常的線程關閉了.所開戶線程的數量要減少一個.
notifyAll(); //喚醒等待串連的阻塞線程.
openThreads(minSpareThreads); //重新開啟minSpareThreads個線程.如currentThreadCount的數量大於minSpareThreads,則還是不開啟新線程.
}
/**
* 調整各種線程隊列數量
*/
protected void adjustLimits() {
if (maxThreads <= 0) { //如果最大線程數小於0
maxThreads = MAX_THREADS; //設定最大線程數為100
}
if (maxSpareThreads >= maxThreads) { //如果最大多餘線程數大於最大線程數.
maxSpareThreads = maxThreads; //設定最大多餘線程數為最大線程數.
}
if (maxSpareThreads <= 0) { //如果最大多餘線程數小於0
if (1 == maxThreads) {
maxSpareThreads = 1; //如最大線程數為1的情況下,設定最大多餘線程數為1.
}
else {
maxSpareThreads = maxThreads / 2; //設定最大多餘線程數為最大線程數的一半.
}
}
if (minSpareThreads > maxSpareThreads) { //如果最小多餘線程大於最大多餘線程數
minSpareThreads = maxSpareThreads; //設定最小多餘線程數為最大多餘線程數.
}
if (minSpareThreads <= 0) { //如果最小多餘線程數小於0
if (1 == maxSpareThreads) {
minSpareThreads = 1; //如最大線程數為1的情況下,則設定最小多餘線程數為1.
}
else {
minSpareThreads = maxSpareThreads / 2; //否則設定最小多餘線程數為最大多餘線程數的一半.
}
}
}
/**
* 開啟指定數量的空閑線程隊列
* @param toOpen int
*/
protected void openThreads(int toOpen) { //toOpen=minSpareThreads
if (toOpen > maxThreads) {
toOpen = maxThreads;
}
if (0 == currentThreadCount) { //如果當前線程池中的線程數量為0
pool = new Vector(toOpen); //建立一個有minSpareThreads數量的Vector
}
//因第二次增加時對第一次增加的線程不能重複增加.所要從currentThreadCount開始.
for (int i = currentThreadCount; i < toOpen; i++) { //先增加minSparethreads數量的線程.
pool.addElement(new ControlRunnable(this)); //Runnable執行個體對象,可用於建立線程
}
currentThreadCount = toOpen;
}
/**
* 監視線程,用於監聽當前空閑線程是否大於最大多餘線程數量,如存在則關閉多餘的空閑線程.
*/
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) { //如果結束
break;
}
p.checkSpareControllers(); //檢查是否有多餘線程.
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
public void stop() {
this.terminate();
}
public synchronized void terminate() {
shouldTerminate = true;
this.notifyAll();
}
}
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.