栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JUC之线程池(总体第四篇)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JUC之线程池(总体第四篇)

1、线程池的优势 (1)概念
  • 之前我们在操作线程的时候都是new Thread,然后使用,然后释放(存在问题就是要加载,释放资源,会浪费资源)。现在不一样了,就我线程池给你new好,准备好,你要使用的时候调用,不用了就释放就好。
  • 同样的JDBC数据库连接池:也是之前学习的概念,连接池给你new准备好,然后你要使用的时候调用即可。
  • 还有的springIOC容器,也是同样的概念。
(2)为什么用线程池

2、如何使用线程池 (1)获取线程池


常用的ExecutorService接口。

  • 我们的Arrays与Collection都有工具类

    我们线程池也肯定有工具类ExecutorService executorService = Executors.newFixedThreadPool(5);//一池五个受理,还有其他的方法
(2)架构原理


开始中使用的就是ThreadPoolExecutor,如果面试问对线程池的理解,那就是对这个类的理解。如何拿到这个类呢,就要通过旁边没有关系的Executors

(3)常用方法调用
  • 固定的newFixedThreadPool:它适用于长期任务性能好,创建一个线程池,一池有N个固定的线程,有固定线程数的线程。

    同一个线程能多次使用。
`ExecutorService executorService = 
                Executors.newFixedThreadPool(5);//一池五个受理`
  • 一池一个类

    感觉有点多此一举,但是它也会有用到的时候。
 ExecutorService executorService =
                Executors.newSingleThreadExecutor();//单例模式
  • 一池可扩容线程

    可以扩展的线程池,当你业务多的时候就多new一点
ExecutorService executorService =
                Executors.newCachedThreadPool();//一池多线程
3、ThreadPoolExecutor原理

我们上一步使用了三种常见的线程池获得的方法中底层都是使用了ThreadPoolExecutor


  • 还使用了阻塞队列
4、线程池底层原理(线程池的七大参数)
 
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
(1)corePoolSize
  • 线程池中的常驻核心线程数,即线程数。
  • 其实就是一个线程池里面有多少个线程。
(2)maximumPoolSize
  • 线程池中能够通纳同时的最大线程值,此值必须大于一。
  • 就是一个业务特别忙的时候,它就会扩容,扩到这个值。
(3)keepAliveTime
  • 多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程就会被销毁直到只剩下corePoolSize 个线程为止。
  • 相当于线程的生命周期,就是当你之前的业务太忙了,现在闲下来了,就再等keepAliveTime的时间,之后就把这些销毁。
(4)unit
  • keepAliveTime的单位。
(5)workQueue
  • 任务队列,被提交但未被执行的任务。
  • 这里就是个阻塞队列:其实就可以理解为候客区一样的概念(当前的线程处理不完请求,剩下的请求就会进入候客区)。
(6)threadFactory
  • 表示生成线程池中工作线程的线程工厂,用于创建线程,一般默认即可。
  • 用于创建线程的
(7)handler
  • 拒绝策略,表示当队列满了,并且工作线程大于等于线程池的最大线程池数(maximumPoolSize)时如何来拒绝请求执行的Runnable的策略。
5、线程池的底层工作原理1 (1)对上面参数的动态理解
  • 如果来请求并且候客区也不满的情况

    来了就给你处理,如果没有corePoolSize的线程给你工作,那你就在候客区等。

  • 如果继续来人(来了6,7,8)

    此时就要扩容了,把你的常驻线程增加到manximumPoolSize。

    此时就可以把3,4,5处理了,然后6,7,8进入候客区。

  • 假设又有人来了(这次来了10个)
    当值窗口和扩容窗口以及候客区都满了,此时就要进行拒绝的Handler来进行处理了。

  • 当你1和2,忙完了就走了,然后6和7就去当值窗口进行办理,然后3,4,5都接着办理完成走了,然后此时加班的窗口的keepAlive就要进行计时了,当到了时间后,就要处理销毁了。

  • 其实就可以理解如下了

    首先提交任务,任何来就要判断核心线程是否有空闲,空闲就接客。如果继续来人,就要在候客区去等。如果继续来人(候客区也满了),就扩容。

(2)线程池用哪个,开发中如何设置参数
  • 常用的肯定是:我感觉是使用可扩容的,but阿里巴巴开发手册里面说啦

    那为什么不适用JDK自带的呢,其实就是如下的原因,21亿的内存,你直接给干爆了

  • 开发的参数如下

6、线程池的底层工作原理2

(1)手写线程池


前面几个参数都比较简单,那最后一个参数的处理策略就要自己思考了,而且其中的new LinkedBlockingQueue它的我们必须设置大小,不然也很危险

  • 看看实现案例

    我们自定义的线程池能使用
    • 继续测试

      增加一个就爆炸了 、它的最大值和我们的队列数。
(2)拒绝处理策略


默认的new ThreadPoolExecutor.AbortPolicy,它直接给报错了。


  • AbortPolicy:阻止系统正常执行

  • CallerRunsPolicy:回退找原来的(之前的谁让你来找我的,你就回退过去找他)

    main线程调用了我,回退给main。而且它还有可能是多个都会退给main处理。

  • DiscardPolicy:Discard抛弃,丢弃无法处理的任务

  • DiscardOldestPolicy:抛弃等待最久的那个。

(3)如何确定线程池的数量呢


看你的业务是IO密集型,还是CPU密集型。

  • 如果是CPU密集型的话,那就CPU加1来设置。
  • IO密集型:CPU核数 / 阻塞系数。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/872705.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号