Java并发 之 线程池系列 (2) 使用ThreadPoolExecutor构造线程池

Executors的“罪与罚”

在上一篇文章Java并发 之 线程池系列 (1) 让多线程不再坑爹的线程池中,我们介绍了使用JDK concurrent包下的工厂和工具类Executors来创建线程池常用的几种方法:

//创建固定线程数量的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);

//创建一个线程池,该线程池会根据需要创建新的线程,但如果之前创建的线程可以使用,会重用之前创建的线程
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

//创建一个只有一个线程的线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

诚然,这种创建线程池的方法非常简单和方便。但仔细阅读源码,却把我吓了一条: 这是要老子的命啊!

我们前面讲过,如果有新的请求过来,在线程池中会创建新的线程处理这些任务,一直创建到线程池的最大容量(Max Size)为止;超出线程池的最大容量的Tasks,会被放入阻塞队列(Blocking
Queue)进行等待,知道有线程资源释放出来为止;要知道的是,阻塞队列也是有最大容量的,多余队列最大容量的请求不光没有获得执行的机会,连排队的资格都没有!

那这些连排队的资格都没有的Tasks怎么处理呢?不要急,后面在介绍ThreadPoolExecutor的拒绝处理策略(Handler Policies for Rejected Task)的时候会详细介绍。

说到这里你也许有写疑惑了,上面这些东西,我通常使用Executors的时候没有指定过啊。是的,因为Executors很“聪明”地帮我们做了这些事情。

Executors的源码

我们看下ExecutorsnewFixedThreadPoolnewSingleThreadExecutor方法的源码:

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

其实它们底层还是通过ThreadPoolExecutor来创建ExecutorService的,这里对妻子的参数先不作介绍,下面会详细讲,这里只说一下new LinkedBlockingQueue<Runnable>()这个参数。

LinkedBlockingQueue就是当任务数大于线程池的线程数的时候的阻塞队列,这里使用的是无参构造,我们再看一下构造函数:

/**
 * Creates a {@code LinkedBlockingQueue} with a capacity of
 * {@link Integer#MAX_VALUE}.
 */
public LinkedBlockingQueue() {
   
    this(Integer.MAX_VALUE);
}

我们看到阻塞队列的默认大小竟然是Integer.MAX_VALUE

如果不做控制,拼命地往阻塞队列里放Task,分分钟“Out of Memory”啊!

还有更绝的,newCachedThreadPool方法:

public static ExecutorService newCachedThreadPool() {
   
    return new ThreadPoolExecutor(
    0, Integer.MAX_VALUE,
    60L, TimeUnit
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值