现在的位置: 首页 > 综合 > 正文

java 线程池技术

2013年09月11日 ⁄ 综合 ⁄ 共 2173字 ⁄ 字号 评论关闭
线程池是管理线程的高级技术,通常它提供了如下功能:
  •   通过对线程的管理,更加合理的调配资源。通常,线程池里维护着一组空闲线程,并向外提供,根据系统繁忙程度动态增加或减少空闲线程的数量。比较高级的还提供了自动检测异常线程的功能。
  •   通过维护池中既存线程,可以节省创建线程的开销,尤其是对于web server这类处理频繁,而处理过程又比较快的程序,创建线程的开销是不能忽略的。

    类似在裸机上加OS能够合理管理计算机资源,使用线程池能够低开销且有效的管理线程的生命周期和系统资源,同时提供更为方便易用的接口对外,使得开发更加快速安全。

    对于简单的线程池,可以参考文章《Java 理论与实践: 线程池与工作队列》
,这里实现了一个简单的带工作队列(Queue)的线程池,当然,也有一些简单的调度,这里就不再赘述。

 

线程池框架


    相对于jdk1.5中的ThreadPoolExecutor中复杂的调度和规划,上面的例子还稍微简单了些。Doug Lee定义了命令模式的接口Executor,使得线程的执行逻辑和时序逻辑得到了分离,提高了健壮性和可扩张性,使得需求变化时不再是将整个程序重写而只需修改相应的执行逻辑----至于时序逻辑,交给ThreadPool吧,它会帮你搞定一切的。不相信?那不如让我们inside ThreadPoolExecutor去看看它是怎么实现这项神奇的功能。

    首先我们对ThreadPoolExecutor的框架来一个总体的认识,ThreadPoolExecutor继承了AbstractExecutorService,后者实现了ExecutorService接口,同时ExecutorService又是Executor的子接口;也就是说ThreadPoolExecutor其实是一个Executor的实现。如图示。

    ThreadPoolExecutor内部共有5个类,其中 RejectExecutionHandler定义了对任务的丢弃方式,它之下有4个实例类。Worker类其实就是在线程池中执行的线程实体,所以它也很重要,可以注意到它被定义为一个内部类,从而可以方便的访问ThreadPoolExecutor类的方法。如图:

    这里简单的先介绍一下这些与ThreadPoolExecutor有关的接口或类。Executor已经介绍过了,就是让逻辑分离而做的接口,它定义了抽象方法execute()。而ExecutorService则是负责管理一组任务的服务接口,它的一些实现都已经在其子类AbstractExecutorService中完成了。ThreadPoolExecutor需要实现execute()和shutdown()等抽象方法。

 

ThreadPoolExecutor代码分析


    execute()是整个线程池最核心的方法,可以说线程池对任务的调度就是在这里实现的。来看for循环,如果当前线程池正在运行,则用reject策略将任务reject掉;如果当前线程数小于核心池数量,就new新线程来解决当前任务,注意即使是活动线程空闲也不会使用它们;一旦线程数超过核心池数量,则不再new新线程,而是向队列中添加任务,这里也分成功失败(队列满则失败),成功说明当前线程数满足当前任务数;失败就表示核心池数量的线程已经不能满足当前任务数了,这时就会启用后备线程;addIfUnderMaximumPoolSize(command)返回的结果其实有三种情况:1.新建线程处理当前任务;2.未新建成功;3.新建线程处理了队列里的任务,但未处理当前任务,前两种情况都在后面用if进行了判断,只有最后的情况是需要 for循环重新处理的。

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        for (;;) {
            if (runState != RUNNING) {
                reject(command);
                return;
            }
            if (poolSize < corePoolSize && addIfUnderCorePoolSize(command))
                return;
            if (workQueue.offer(command))
                return;
            Runnable r = addIfUnderMaximumPoolSize(command);
            if (r == command)
                return;
            if (r == null) {
                reject(command);
                return;
            }
            // else retry
        }
    }

 

  更多,请参阅http://www.360watcher.net/html/35/656.htm

抱歉!评论已关闭.