• 多线程


    1.线程池参数

    2.线程池执行流程

    2.1 流程图

    2.2 线程创建的流程


    当任务提交之后,线程池首先会检查当前线程数,如果当前的线程数小于核心线程数(corePoolSize),比如最开始创建的时候线程数为 0,则新建线程并执行任务。
    当提交的任务不断增加,创建的线程数等于核心线程数(corePoolSize),新增的任务会被添加到 workQueue 任务队列中,等待核心线程执行完当前任务后,重新从 workQueue 中获取任务执行。
    假设任务非常多,达到了 workQueue 的最大容量,但是当前线程数小于最大线程数(maximumPoolSize),线程池会在核心线程数(corePoolSize)的基础上继续创建线程来执行任务。
    假设任务继续增加,线程池的线程数达到最大线程数(maximumPoolSize),如果任务继续增加,这个时候线程池就会采用拒绝策略来拒绝这些任务。

    2.3 小结


    在任务不断增加的过程中,线程池会逐一判断

    核心线程数(corePoolSize)
    任务队列(workQueue)
    最大线程数(maximumPoolSize)
    拒绝策略


    3.核心线程数和最大线程数


    corePoolSize 是核心线程数,初始大小是 0,但是在创建线程之后,核心线程会常驻在线程池中,即使没有任务执行,也不会被销毁。随着任务数的增加,当任务队列(workQueue )满了之后,线程池根据最大线程数(maximumPoolSize)来创建非核心线程,当任务执行完,线程有空闲,非核心线程会被回收。

    “正式员工” 与 “外包员工”

    一般大型银行会有很多项目要做,但是银行的正式编制有限,这种时候就需要采用“人力外包”的形式。corePoolSize 相当于正式员工,而 (maximumPoolSize - corePoolSize) 相当于外包员工,当项目比较少的时候,正式员工就可以处理,但是项目增多时超过了处理负荷,就需要增加外包人员协助进行处理。

    当项目完成或者结束之后,正式员工还是在银行上班,等待任务或者处理新的任务,而外包人员则会结束和银行的合同。

    4.keepAliveTime+时间单位


    第三个参数是 keepAliveTime + 时间单位,当线程池中线程数量多于核心线程数时,而此时又没有任务可做,线程池就会检测线程的 keepAliveTime,如果超过规定的时间,无事可做的线程就会被销毁,以便减少内存的占用和资源消耗。如果后期任务又多了起来,线程池也会根据规则重新创建线程,所以这是一个可伸缩的过程,比较灵活,我们也可以用 setKeepAliveTime 方法动态改变 keepAliveTime 的参数值。

    5.ThreadFactory

    ThreadFactory 使用的是抽象工厂模式

    第四个参数是 ThreadFactory,ThreadFactory 实际上是一个线程工厂,它的作用是生产线程以便执行任务。我们可以选择使用默认的线程工厂,创建的线程都会在同一个线程组,并拥有一样的优先级,且都不是守护线程,我们也可以选择自己定制线程工厂,以方便给线程自定义命名,不同的线程池内的线程通常会根据具体业务来定制不同的线程名。

    为什么创建的线程不是守护线程?

    守护线程:和主线程一起结束的线程,叫守护线程。
    非守护线程:主线程的结束不影响线程的执行的线程,也叫用户线程。

    源码如下:

            public Thread newThread(Runnable r) {
                Thread t = new Thread(group, r,
                                      namePrefix + threadNumber.getAndIncrement(),
                                      0);
                if (t.isDaemon())// 判断是否是守护线程
                    t.setDaemon(false);// 如果是则设置为 false
                if (t.getPriority() != Thread.NORM_PRIORITY)
                    t.setPriority(Thread.NORM_PRIORITY);// 设置优先级为 5 
                return t;
            }

    有源码可知,如果线程是守护线程,会重新设置为非守护线程,而设置为非守护线程的原因是保证该线程不受主线程的影响。

    6.workQueue 阻塞队列

    阻塞队列,后续专题章节进行讲解:线程池常用的阻塞队列有哪些

    7.Handler 拒绝策略

    拒绝策略,后续专题章节进行讲解:线程池的4种拒绝策略

    参考文献

    版权声明:本文为CSDN博主「不懂的浪漫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/xiewenfeng520/article/details/106954170/

  • 相关阅读:
    jquery使用ajax
    Docker下使用centos无法使用systemctl怎么办
    memcache安装及解决无法远程连接的问题
    NetCore控制台程序-使用HostService和HttpClient实现简单的定时爬虫
    PHP代码审计01
    路由和交换-
    路由和交换-VLAN
    路由和交换-FTP配置
    51job招聘信息爬虫
    豆瓣电影排行250爬虫
  • 原文地址:https://www.cnblogs.com/frankcui/p/15405806.html
Copyright © 2020-2023  润新知