当在应用中需要限制某一时刻的线程的数量的时候线程池就很有用了。开启一个新的线程的时候会有性能上的开销,而且每一个线程需要为它的栈等分配一些内存。
与为当前执行的线程开启一个新的线程相反的是,这个工作可以交于线程池来处理。一旦池中有空闲的线程,任务就会被分配线程池中的一个并且执行它。在内部,任务被插入到Blocking Queue,线程池中的线程也是在这里出队的。当一个新的任务插入到队列中的时候,一个空闲的线程将会出队并且执行它,线程池中的其他线程会因等待出队的任务而阻塞。
线程池常常用在多线程的服务器上,通过网络每一个连接服务器的连接会被包装成一个任务并传递到线程池中去。线程池中的线程将会处理当前连接的请求,一会我们会介绍java怎么实现多线程服务器。java5中可以使用java.util.concurrent 包来构建线程池。所以你不必实现你自己的线程池,你可以在我的文章中了解更多的东西java.util.concurrent.ExecutorService,稍稍了解一下如何实现线程池的还是非常有用的。
下边这是一个非常简单的线程池的实现,请注意这个实现使用了我自己的BlockingQueue类,我在这篇文中解释了它。在实际的应用中,你最好使用java内嵌的阻塞队列替代。
public class ThreadPool {
private BlockingQueue taskQueue = null;
private List<PoolThread> threads = new ArrayList<PoolThread>();
private boolean isStopped = false;
public ThreadPool(int noOfThreads, int maxNoOfTasks){
taskQueue = new BlockingQueue(maxNoOfTasks);
for(int i=0; i<noOfThreads; i++){
threads.add(new PoolThread(taskQueue));
}
for(PoolThread thread : threads){
thread.start();
}
}
public synchronized void execute(Runnable task) throws Exception{
if(this.isStopped) throw
new IllegalStateException("ThreadPool is stopped");
this.taskQueue.enqueue(task);
}
public synchronized void stop(){
this.isStopped = true;
for(PoolThread thread : threads){
thread.doStop();
}
}
}
public class PoolThread extends Thread {
private BlockingQueue taskQueue = null;
private boolean isStopped = false;
public PoolThread(BlockingQueue queue){
taskQueue = queue;
}
public void run(){
while(!isStopped()){
try{
Runnable runnable = (Runnable) taskQueue.dequeue();
runnable.run();
} catch(Exception e){
//log or otherwise report exception,
//but keep pool thread alive.
}
}
}
public synchronized void doStop(){
isStopped = true;
this.interrupt(); //break pool thread out of dequeue() call.
}
public synchronized boolean isStopped(){
return isStopped;
}
}
线程池的实现包含两个部分。一个ThreadPool类是线程池的一个公共接口,PoolThrea类实现了执行任务的Thread。为了执行任务ThreadPool.execute(Runnable r)这个方法,将会被调用。这个Runnable进入阻塞队列,等待出队。Runnable将会通过一个一个空闲的PoolThread的执行进行出队的操作。你可以看一下这个PoolThread.run()方法,当执行完PoolThread循环的时候,它试图再一次的将任务出队,直到它停止。
原文地址:http://tutorials.jenkov.com/java-concurrency/thread-pools.html