本篇主要用作鏈接使用窑滞。
線(xiàn)程池的核心就是哀卫,當(dāng)接收到一個(gè)任務(wù)撬槽,需要一個(gè)線(xiàn)程去執(zhí)行時(shí)侄柔,并不著急創(chuàng)建一個(gè)線(xiàn)程暂题,而是先去線(xiàn)程池檢查是否有空閑的線(xiàn)程,如果有挂滓,則直接使用赶站,如果沒(méi)有則創(chuàng)建新的線(xiàn)程纺念,然后執(zhí)行任務(wù)陷谱。任務(wù)執(zhí)行完成后,也不著急銷(xiāo)毀線(xiàn)程铺根,而是將線(xiàn)程放到線(xiàn)程池的空閑隊(duì)列中乔宿,等待下次使用详瑞。
首先是線(xiàn)程池的實(shí)現(xiàn)坝橡。
首先是線(xiàn)程池的實(shí)現(xiàn):
/**
* Created by Joker on 2015/3/7.
*/
public class ThreadPool {
private static ThreadPool instance = null;
//空閑的線(xiàn)程隊(duì)列
private List<JThread> idleThreads;
//已有的線(xiàn)程總數(shù)
private int threadCounter = 0;
private Boolean isShunDown = false;
public ThreadPool() {
//初始化空閑線(xiàn)程隊(duì)列容量為5
this.idleThreads = new Vector<JThread>(5);
this.threadCounter = 0;
}
private static class SingleTonHolder {
private static ThreadPool threadPool = new ThreadPool();
}
/*單例獲得線(xiàn)程池實(shí)例*/
public static ThreadPool getInstance() {
return SingleTonHolder.threadPool;
}
public int getThreadCounter() {
return threadCounter;
}
/**
* 將線(xiàn)程放入池中计寇,回收線(xiàn)程
*/
protected synchronized void repool(JThread repoolingThread) {
if (!isShunDown) {
idleThreads.add(repoolingThread);
} else {
repoolingThread.shutDown();
}
}
/**
* 停止池中所有線(xiàn)程
*/
public synchronized void shutDownAll() {
this.isShunDown = true;
for (JThread jThread : idleThreads) {
jThread.shutDown();
}
}
/**
* 執(zhí)行線(xiàn)程任務(wù)
*/
public synchronized void execute(Runnable target) {
this.isShunDown = false;
JThread jThread = null;
/*如果池中有空余線(xiàn)程饲常,直接使用該線(xiàn)程*/
if (idleThreads.size() > 0) {
jThread = idleThreads.get(idleThreads.size() - 1);
//將該線(xiàn)程從池中移除
idleThreads.remove(jThread);
//立即執(zhí)行該任務(wù)
jThread.setTarget(target);
}
/*沒(méi)有空閑線(xiàn)程贝淤,創(chuàng)建新線(xiàn)程*/
else {
threadCounter++;
//創(chuàng)建線(xiàn)程
jThread = new JThread(target, "JThread:" + threadCounter, ThreadPool.this);
jThread.start();
}
}
}
要使用上述線(xiàn)程池播聪,還需要一個(gè)永不退出的工作現(xiàn)場(chǎng)與之配合离陶。是一個(gè)While
循環(huán),手動(dòng)關(guān)閉之前霎俩,永不結(jié)束打却,一直等待新的任務(wù)進(jìn)來(lái)柳击。
該工作線(xiàn)程的實(shí)現(xiàn)如下:
/**
* Created by Joker on 2015/3/7.
*/
public class JThread extends Thread {
//線(xiàn)程池
private ThreadPool threadPool;
//任務(wù)
private Runnable target;
private boolean isShutDown = false;
private boolean isIdle = false;
public JThread(Runnable target, String name, ThreadPool threadPool) {
super(name);
this.target = target;
this.threadPool = threadPool;
}
public Runnable getTarget() {
return target;
}
public boolean isIdle() {
return isIdle;
}
@Override
public void run() {
//只要沒(méi)有關(guān)閉捌肴,則一直不結(jié)束該線(xiàn)程
while (!isShutDown) {
isIdle = false;
if (null != target) {
//執(zhí)行任務(wù),注意這里調(diào)用的是run(),而不是start()
target.run();
}
//任務(wù)結(jié)束筝蚕,閑置狀態(tài)
isIdle = true;
try {
threadPool.repool(JThread.this);
synchronized (this) {
//線(xiàn)程空閑铺坞,等待新的任務(wù)到來(lái)
wait();
}
} catch (InterruptedException e) {
}
isIdle = false;
}
}
public synchronized void setTarget(Runnable target) {
this.isShutDown = false;
this.target = target;
//設(shè)置任務(wù)之后济榨,通知run方法擒滑,開(kāi)始執(zhí)行任務(wù)
notifyAll();
}
/**
* 關(guān)閉線(xiàn)程
*/
public synchronized void shutDown() {
this.isShutDown = true;
notifyAll();
}
}
使用方法如下:
ThreadPool.getInstance().execute(new Runnable() {
@Override
public void run() {
/*執(zhí)行任務(wù)*/
}
});