以下内容转自http://ifeve.com/thread-pools/

线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用。因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等。

我们可以把并发执行的任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程。只要池里有空闲的线程,任务就会分配给一个线程执行。在线程池的内部,任务被插入一个阻塞队列(Blocking Queue ),线程池里的线程会去取这个队列里的任务。当一个新任务插入队列时,一个空闲线程就会成功的从队列中取出任务并且执行它。

线程池经常应用在多线程服务器上。每个通过网络到达服务器的连接都被包装成一个任务并且传递给线程池。线程池的线程会并发的处理连接上的请求。以后会再深入有关Java实现多线程服务器的细节。

Java 5在java.util.concurrent包中自带了内置的线程池,所以你不用非得实现自己的线程池。你可以阅读我写的java.util.concurrent.ExecutorService的文章以了解更多有关内置线程池的知识。不过无论如何,知道一点关于线程池实现的知识总是有用的。

这里有一个简单的线程池实现:

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;
}
}

(校注:原文有编译错误,我修改了下)

public class PoolThread extends Thread {

  private BlockingQueue<Runnable> taskQueue = null;
private boolean isStopped = false; public PoolThread(BlockingQueue<Runnable> queue) {
taskQueue = queue;
} public void run() {
while (!isStopped()) {
try {
Runnable runnable =taskQueue.take();
runnable.run();
} catch(Exception e) {
// 写日志或者报告异常,
// 但保持线程池运行.
}
}
} public synchronized void toStop() {
isStopped = true;
this.interrupt(); // 打断池中线程的 dequeue() 调用.
} public synchronized boolean isStopped() {
return isStopped;
}
}

线程池的实现由两部分组成。类ThreadPool是线程池的公开接口,而类PoolThread用来实现执行任务的子线程。

为了执行一个任务,方法ThreadPool.execute(Runnable r)Runnable的实现作为调用参数。在内部,Runnable对象被放入阻塞队列 (Blocking Queue),等待着被子线程取出队列。

一个空闲的PoolThread线程会把Runnable对象从队列中取出并执行。你可以在PoolThread.run()方法里看到这些代码。执行完毕后,PoolThread进入循环并且尝试从队列中再取出一个任务,直到线程终止。

调用ThreadPool.stop()方法可以停止ThreadPool。在内部,调用stop先会标记isStopped成员变量(为 true)。然后,线程池的每一个子线程都调用PoolThread.stop()方法停止运行。注意,如果线程池的execute()stop()之后调用,execute()方法会抛出IllegalStateException异常。

子线程会在完成当前执行的任务后停止。注意PoolThread.stop()方法中调用了this.interrupt()。它确保阻塞在taskQueue.dequeue()里的wait()调用的线程能够跳出wait()调用(校对注:因为执行了中断interrupt,它能够打断这个调用),并且抛出一个InterruptedException异常离开dequeue()方法。这个异常在PoolThread.run()方法中被截获、报告,然后再检查isStopped变量。由于isStopped的值是true, 因此PoolThread.run()方法退出,子线程终止。

(校对注:看完觉得不过瘾?更详细的线程池文章参见Java线程池的分析和使用

最新文章

  1. 关于在header里增加参数的方式
  2. TAP/TUN摘要
  3. T-SQL中的一些小陷阱
  4. MapKit地图划线
  5. hdu 1097 A hard puzzle
  6. 关于JQuery的一些知识点
  7. 烂泥:为KVM虚拟机添加网卡
  8. 微价值:专访《甜心爱消除》的个人开发者Lee,日入千元
  9. bzoj1197
  10. ClusterWare 服务介绍
  11. 配置你的Editor
  12. ABP之多租户
  13. Nginx 安装与部署配置以及Nginx和uWSGI开机自启
  14. pwnable.kr simple login writeup
  15. vue 中如何对公共css、 js 方法进行单文件统一管理,全局调用
  16. Google Maps瓦片(tile)地图文件下载(1-11层级)
  17. 20155226《网络攻防》 Exp3 免杀原理与实践
  18. h5 rem
  19. 20135234mqy-——信息安全系统设计基础第十周学习总结
  20. Java访问者模式

热门文章

  1. {Python}安装第三方包(setup.py)
  2. Linux系统资源监控--linux命令、nmon和spotlight
  3. vue学习图解
  4. VS2015 安装包缺失(联网安装失败)问题解决
  5. Jmeter之重定向请求
  6. CAD从二进流加载数据(com接口VB语言)
  7. 梦想CAD控件网页版扩展数据
  8. java虚拟机(八)--java性能监控与故障处理工具
  9. Analysis of container and Injection in Java, their history and future.
  10. vue基础---事件处理