首先介绍一下为什么要使用线程池?使用线程池的原因是因为线程的创建和销毁的代价是比较高的,而且是与业务无关的。一般情况下,我们会想着把CPU用在处理具体的业务上面,而不是用在辅助业务的创建和销毁上面,所以就有了线程池。
线程池类:
public class ThreadPool {
private static ThreadPool instance = null;
//空闲的线程队列
private List<Worker> idleThreads;
//已有的线程总数
private int threadCounter;
private boolean isShutDown = false;
private ThreadPool(){
this.idleThreads = new Vector(5);
threadCounter = 0;
}
public int getCreatedThreadsCount(){
return threadCounter;
}
//取得线程池的实例
public synchronized static ThreadPool getInstance(){
if(instance == null){
instance = new ThreadPool();
}
return instance;
}
//将线程放入池中
protected synchronized void repool(Worker repoolingThread){
if(!isShutDown){
idleThreads.add(repoolingThread);
}else{
//关闭线程
repoolingThread.shutDown();
}
}
//停止池中的所有线程
public synchronized void shutdown(){
isShutDown = true;
for(int threadIndex = 0; threadIndex < idleThreads.size(); threadIndex++){
Worker idleThread = (Worker)idleThreads.get(threadIndex);
idleThread.shutDown();
}
}
//执行任务
public synchronized void start(Runnable target){
Worker thread = null;
//如果有空闲线程,则直接使用
if(idleThreads.size() > 0){
int lastIndex = idleThreads.size() - 1;
thread = (Worker)idleThreads.get(lastIndex);
idleThreads.remove(lastIndex);
//立即执行这个任务
thread.setTarget(target);
}else{
//没有空闲线程,则创建新线程
threadCounter++;
//创建新线程
thread = new Worker(target, "PThread #"+threadCounter, this);
//启动这个线程
thread.start();
}
}
}
Worker类:
public class Worker extends Thread{
//线程池
private ThreadPool pool;
//任务
private Runnable target;
private boolean isShutDown = false;
private boolean isIdle = false;
public Worker(Runnable target, String name, ThreadPool pool){
super(name);
this.pool = pool;
this.target = target;
}
public Runnable getTarget(){
return target;
}
public boolean isIdle(){
return isIdle;
}
public void run(){
while(!isShutDown){
isIdle = false;
if(target != null){
//运行任务
target.run();
}
//任务结束了
isIdle = true;
try{
//该任务结束后,不关闭线程,而是放入线程池空闲队列
pool.repool(this);
synchronized(this){
//线程空闲,等待新的任务到来
wait();
}
}catch(InterruptedException ie){
}
isIdle = false;
}
}
public synchronized void setTarget(java.lang.Runnable newTarget){
target = newTarget;
//设置了任务之后,通知run方法开始执行这个任务
notifyAll();
}
public synchronized void shutDown(){
isShutDown = true;
notifyAll();
}
}