为什么要使用线程池?

1、创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率。
   例如:记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3
      如果T1+T3>T2,那么是不是说开启一个线程来执行这个任务太不划算了!
                正好,线程池缓存线程,可用已有的闲置线程来执行新任务,避免了T1+T3带来的系统开销。

2、线程并发数量过多,抢占系统资源从而导致阻塞。
      我们知道线程能共享系统资源,如果同时执行的线程过多,就有可能导致系统资源不足而产生阻塞的情况。
      运用线程池能有效的控制线程最大并发数,避免以上的问题。

3、对线程进行一些简单的管理,比如:延时执行、定时循环执行的策略等,运用线程池都能进行很好的实现。

所以,在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程。

这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了资源的开销。

那我们就按照手册来吧:

如何创建一个线程池呢?

在 Java 中,新建一个线程池对象非常简单,Java 本身提供了工具类 java.util.concurrent.Executors。

可以使用如下代码创建一个固定数量线程的线程池:

ExecutorService service = Executors.newFixedThreadPool(10);

注意:以上代码用来测试还可以,实际使用中最好能够显示地指定相关参数。

我们可以看下其内部源码实现:

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

在阿里巴巴代码规范中,建议我们自己指定线程池的相关参数,为的是让开发人员能够自行理解线程池创建中的每个参数。

根据实际情况,创建出合理的线程池。接下来,我们来剖析下 java.util.concurrent.ThreadPoolExecutor 的构造方法参数。

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

构造函数的参数含义如下:

corePoolSize:   指定了线程池中的线程数量,它的数量决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去;

maximumPoolSize:   指定了线程池中的最大线程数量,这个参数会根据你使用的workQueue任务队列的类型,决定线程池会开辟的最大线程数量;

keepAliveTime:   当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁;

unit:   keepAliveTime的单位;

workQueue:   任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种;

threadFactory:   线程工厂,用于创建线程,一般用默认即可; // 后面默认的参数 defaultThreadFactory()

handler:   拒绝策略,当任务太多来不及处理时,如何拒绝任务; // 后面默认的参数 defaultHandler

 

posted @ 2021-04-01 14:13  M-Anonymous  阅读(554)  评论(0)    收藏  举报