网站首页 新闻首页 网页设计图形动画软件编程网站开发办公软件操作系统数据库网络技术认证考试范文资料黑客攻防 书籍教程 进入论坛

Tomat组件研究之ThreadPool

http://www.diybl.com/ 2007-2-6  网络 点击:  [ 评论 ]
文章搜索:    【点击打包该文章】


Tomat组件研究之ThreadPool

   前几天曾向大家承诺,要完成ThredPool,Tomcat SSl的文章,今天终于有时间可以写一点。Tomcat的ThradPool不同于Apache的Common ThradPool,Tomcat的ThreadPool是专门为Tomcat服务的,确切说是为Tomcat处理Http连接服务地。经过研究发现,Apache用了及其难懂而又隐晦的方法写了这几个ThreadPool类,虽然仅简单的几个类,但其难理解的程度却是惊人的。在理解之后看,里面确实又值得我们学习的东西,但也有好多无用的东西。看来我们也不要盲目崇拜Apache。废话少说,下面直入正题.

ThreadPool的Class图及整体结构:



一.每个类的说明:







1.   org.apache.tomcat.util.threads.ThreadPool







   线程池类,本类仅维护一定数量的线程处理对象,而把具体执行操作的任务委派给其他对象(ControlRunnable),Apache并没有把过多的功能交给这个类,而仅只是让这个类维护线程的创建,销毁,取出,归还等功能。下面我们看该类的代码:







public class ThreadPool  {







(1)      线程池常量,对应的变量设置就不再列出了







    //最大线程数







    public static final int MAX_THREADS = 200;







//最大线程数的最小数(最大线程的数量不能小于这个数)







    public static final int MAX_THREADS_MIN = 10;







//最大空闲线程数







    public static final int MAX_SPARE_THREADS = 50;







//最小空闲线程数(当线程池初始化时就启动这么多线程)







    public static final int MIN_SPARE_THREADS = 4;







//最大等待时间(1分钟)







    public static final int WORK_WAIT_TIMEOUT = 60*1000;







(2)      start方法








 


 



//对每个线程实例本方法仅被调用一次







    public synchronized void start() {







        //是否停止线程







        stopThePool=false;







        //当前生成线程的数量







        currentThreadCount  = 0;







        //当前使用线程的数量







        currentThreadsBusy  = 0;







        //如果当前设置的各个参数不正确,调整一下







        adjustLimits();







        //生成空的线程池







        pool = new ControlRunnable[maxThreads];







        //启动最小线数线程







        openThreads(minSpareThreads);







        //启动监视线程,监视线程池内部状态







        monitor = new MonitorRunnable(this);







}







(3)      openThreads方法







/**







* 启动指定数量(toOpen)的线程







* 这个方法很是奇怪,这个toOpen并不是本次打开的的线程数







* 而是本次要打开的和以前已经打开的线程数总和







*/







    protected void openThreads(int toOpen) {








 


 



        if(toOpen > maxThreads) {







            toOpen = maxThreads;







        }







        //新打开的线程数放在已经存在的空闲线程后面(用数组存放)







        for(int i = currentThreadCount ; i < toOpen ; i++) {







            pool[i - currentThreadsBusy] = new







ControlRunnable(this);







        }







        currentThreadCount = toOpen;







    }







到这里我们感觉Apache的做法好生奇怪,首先这个toOpen,还有一点,以前我们写连接池时,都时用List作为容器,一般有个当前的空闲线程数,但Apache偏偏用数组作为容器来存放线程,用数组就要维护每种线程(新的,使用的,空闲的)在数组中的下标,若用List这些问题就没了,我们只要get,add,remove一下就一切OK,非常方便。因为有了currentThreadsBusy,Apache的当前的空闲线程数就必须用currentThreadCount- currentThreadsBusy计算得来。这就时我们为什么会看到上面那个奇怪得小循环。但用数组到底有什么好处呢,还是Apache的人是猪头(靠,他们不可能是猪头)?,我们可能发现上面有个常量:








 


 



//最大线程数







    public static final int MAX_THREADS = 200;







           也就是说,默认最多池可以有200个线程,就是说有很多线程可能频繁地从池中







            取,放线程,如果用List效率将大打折扣,因此才用了数组。







(4)      findControlRunnable方法,取得一个可用线程







private ControlRunnable findControlRunnable() {







        ControlRunnable c=null;








 


 



        if ( stopThePool ) {







            throw new IllegalStateException();







        }

欢迎光临DIY部落,点击这里查看更多文章教程   【点击打包该文章】
如果图片或页面不能正常显示请点击这里 站内搜索:   

文章评论

请您留言