核心线程池的内部细节

对于核心的几个线程池,无论是newFixedThreadPool()方法,newSingleThreadExecutor(),还是newCachedThreadPool()方法,内部均使用了ThreadPoolExecutor实现。

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

ThreadPoolExecutor

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
}

函数的参数含义如下:
corePoolSize:指定了线程池中线程数量
maximunPoolSize:指定了线程池中最大线程数量
keepAliveTime:当线程池线程数量超过corePoolSize时,多余空闲线程的的存活时间。
unit:keepAliveTime的单位
workQueue:任务队列,被提交但尚未被执行的任务。
threadFactory:线程工厂,用于创建线程
handler:拒接策略,当任务太多来不及处理,如何拒接任务。

任务队列workQueue
参数workQueue指被提交但未执行的任务队列,它是一个BlockingQueue接口的对象,仅用于存放Runnable对象。根据功能分类。有以下几种BlockingQueue
①直接提交队列,功能由SynchronousQueue提供:
使用SynchronousQueue提交的任务不会被真实的保存,而总是将新任务提交给线程执行,如果没有空闲的线程,则尝试创建新的线程,如果进程数量已经达到最大值,则执行拒绝策略。因此使用SynchronousQueue队列,通常需要设置很大的maximumPoolSize值。
②有界的任务队列,功能由ArrayBlockingQueue提供:
使用ArrayBlockingQueue时,若有新的任务需要执行,如果线程池的实际线程数小于corePoolSize,则会有限创建新的线程,若大于corePoolSize,则会将新任务加入等待队列。若队列已满,无法加入,则会在总线程数不大于maximumPoolSize的前提下,创建新的线程执行任务。若大于maximumPoolSize,则执行拒接策略。
③无界的任务队列,功能由对LinkedBlockingQueue提供:
与有界队列相比,除非系统资源耗尽,否则无界的任务队列不会存在任务入队失败的情况。当有新的任务到来,系统的线程数小于corePoolSize时,线程池会创建新的线程执行任务,但当线程数达到corePoolSize后,又有新的任务加入,则任务会进入队列等待。若任务的创建速度和处理速度差异很大,无界队列就会快速增长,直到耗尽系统内存。
④优先任务队列:功能由PriorityBlockingQueue提供:
它时一个特殊的无界队列,前面的ArrayBlockingQueue和LinkedBlockingQueue都是按照先进先出处理任务的。而PriorityBlockingQueue可以根据任务自身的优先级顺序先后执行。在确保系统性能的同时,也能有很好的质量保证。

拒接策略handler
JDK内置的拒接策略如下
①AbortPolicy策略:该策略直接抛出异常,组织系统正常工作
②CallerRunsPolicy策略:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。这个做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。
③DiscardOledestPolicy策略:该策略将丢弃最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。
④DiscardPolicy策略:默默的丢弃无法处理的任务,不给予任何处理
同时JDK还提供了RejectedExecutionHandler接口自定义实现拒接策咯

public interface RejectedExecutionHandler {
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}
                                                                  --参考书籍《Java高并发程序设计》

猜你喜欢

转载自blog.csdn.net/XlxfyzsFdblj/article/details/79709687