Java并发编程---线程池原理分析

最近看了线程池相关,进行相关记录;
线程池工作流程
在这里插入图片描述

一.首先,线程池的优点如下:
1)控制线程数量;
2)减低频繁创造和销毁线程;
3)对于任务的响应速度更快;
二.Executors详解
在入门的时候,可以了解到通过Executors进行创建线程池

     // 只有一个核心线程的线程池
      ExecutorService executorService = Executors.newSingleThreadExecutor();

      // 固定线程数的线程池
      ExecutorService executorService1 = Executors.newFixedThreadPool(3);

      // 伸缩性,60s回收
      ExecutorService executorService2 = Executors.newCachedThreadPool();

这三者,他们的底层都是如下实现如下方法:

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

1、corePoolSize(线程池基本大小):当向线程池提交一个任务时,若线程池已创建的线程数小于corePoolSize,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务,直到已创建的线程数大于或等于corePoolSize时,(除了利用提交新任务来创建和启动线程(按需构造),也可以通过 prestartCoreThread() 或 prestartAllCoreThreads() 方法来提前启动线程池中的基本线程。)

2、maximumPoolSize(线程池最大大小):线程池所允许的最大线程个数。当队列满了,且已创建的线程数小于maximumPoolSize,则线程池会创建新的线程来执行任务。另外,对于无界队列,可忽略该参数。

3、keepAliveTime(线程存活保持时间)当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数。

4、workQueue(任务队列):用于传输和保存等待执行任务的阻塞队列。

5、threadFactory(线程工厂):用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)。

5、handler(线程饱和策略):当线程池和队列都满了,再加入线程会执行此策略。
那么,在工作中,我们一般选择怎么创建线程池呢?
先公布答案,以上三种都不采纳; 因为阿里巴巴开发手册告诉我们,不推荐使用这三个创建,如果要使用,需要我们自己实现TreadPoolExecutor。
为什么不可以使用上面三个创建线程池呢?
1,首先newCachedThreadPool的源码中

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

在这里插入图片描述
很显然,它的maximumPoolSize参数的最大值为Integer.MAX_VALUE,即大约为21亿;如果数据量大的话,大量线程创建,就会造成OOM;
2.newSingleThreadExecutor和newFixedThreadPool中,则是

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

在这里插入图片描述

在这里插入图片描述
它们允许请求队列的长度为Integer.MAX_VALUES,会堆积大量的请求,造成OOM;

三.对于execute()和submit()方法
1.execute(),执行一个任务,没有返回值;而submit()有返回值
2.execute()执行出现异常,可以抛出;而submit()不会抛出异常
3.exectue()只能接受Runnable接口;而submit()可以Callable或者Runnable;

借鉴相关博客:
http://ifeve.com/java-threadpool/
https://blog.csdn.net/ityouknow/article/details/82393099

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

virtuousOne

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值