首页 > 其他分享 >使用ThreadPoolExecutor线程池消化线程执行代码

使用ThreadPoolExecutor线程池消化线程执行代码

时间:2024-10-31 16:21:51浏览次数:1  
标签:poolExecutor 队列 代码 任务 线程 执行 excutorRunnable ThreadPoolExecutor

此处记录一个使用ThreadPoolExecutor线程池的demo

线程代码

public class ExcutorRunnable implements Runnable{

    @Override
    public void run() {

        System.out.println(Thread.currentThread().getName() + ": 线程执行666");
        try {
            Thread.sleep(Integer.MAX_VALUE);  //此处是想看下后面拒绝策略
        } catch (InterruptedException e) {

        }
    }
}

测试main方法

public class ThreadExcutorPool {

    public static void main(String[] args) {

        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3,5,8,
                TimeUnit.SECONDS,new ArrayBlockingQueue<>(4),
                Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());
        //ExecutorService service = new ScheduledThreadPoolExecutor()
        Runnable excutorRunnable = new ExcutorRunnable();
        poolExecutor.execute(excutorRunnable);
        poolExecutor.execute(excutorRunnable);
        poolExecutor.execute(excutorRunnable);
        //放到队列中
        poolExecutor.execute(excutorRunnable);
        poolExecutor.execute(excutorRunnable);
        poolExecutor.execute(excutorRunnable);
        poolExecutor.execute(excutorRunnable);
        //最大线程
        poolExecutor.execute(excutorRunnable);
        poolExecutor.execute(excutorRunnable);
        //执行拒绝策略
        poolExecutor.execute(excutorRunnable);

    }

}

控制台打印

pool-1-thread-2: 线程执行666
main: 线程执行666
pool-1-thread-4: 线程执行666
pool-1-thread-3: 线程执行666
pool-1-thread-5: 线程执行666
pool-1-thread-1: 线程执行666

上面的demo中,为啥创建线程的时候,睡眠时间这么久呢,就是想看下,如果这个核心线程数满了,队列也满了,会不会创建空闲线程数,如果空闲线程数也满了,执行的线程策略中,使用CallerRunsPolicy,会不会就当前线程执行该人去,从打印的控制台来看,是有执行

这里线程池的创建中有几个参数

 

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
}

每个参数的具体描述

线程池(ThreadPoolExecutor)有 7 个参数,这 7 个参数的含义如下:

  1. 第 1 个参数:corePoolSize 表示线程池的常驻核心线程数。如果设置为 0,则表示在没有任何任务时,销毁线程池;如果大于 0,即使没有任务时也会保证线程池的线程数量等于此值。但需要注意,此值如果设置的比较小,则会频繁的创建和销毁线程(创建和销毁的原因会在本课时的下半部分讲到);如果设置的比较大,则会浪费系统资源,所以开发者需要根据自己的实际业务来调整此值;

  2. 第 2 个参数:maximumPoolSize 表示线程池在任务最多时,最大可以创建的线程数。官方规定此值必须大于 0,也必须大于等于 corePoolSize,此值只有在任务比较多,且不能存放在任务队列时,才会用到;

  3. 第 3 个参数:keepAliveTime 表示线程的存活时间,当线程池空闲时并且超过了此时间,多余的线程就会销毁,直到线程池中的线程数量销毁的等于 corePoolSize 为止,如果 maximumPoolSize 等于 corePoolSize,那么线程池在空闲的时候也不会销毁任何线程;

  4. 第 4 个参数:unit 表示存活时间的单位,它是配合 keepAliveTime 参数共同使用的;

  5. 第 5 个参数:workQueue 表示线程池执行的任务队列,当线程池的所有线程都在处理任务时,如果来了新任务就会缓存到此任务队列中排队等待执行;

  6. 第 6 个参数:threadFactory 表示线程的创建工厂,此参数一般用的比较少,我们通常在创建线程池时不指定此参数,它会使用默认的线程创建工厂的方法来创建线程;

  7. 第 7 个参数:RejectedExecutionHandler 表示指定线程池的拒绝策略,当线程池的任务已经在缓存队列 workQueue 中存储满了之后,并且不能创建新的线程来执行此任务时,就会用到此拒绝策略,它属于一种限流保护的机制。

 

关于第五个参数阻塞队列:有几种常见的策略

ArrayBlockingQueue:由数组结构组成的有界阻塞队列。

LinkedBlockingQueue:由链表结构组成的有界阻塞队列。

DelayQueue:使用优先级队列实现的无界阻塞队列。

PriorityBlockingQueue:至此优先级排序的无界阻塞队列。

SynchronousQueue:不储存元素的阻塞队列。

  1. 直接提交策略(Direct handoff): 当线程池的工作队列已满时,该策略会立即将任务交给线程池中的工作线程进行执行,并且不会将任务保存在队列中。这意味着任务提交立即与任务执行同步进行,不会进行任何形式的排队等待。如果没有空闲的工作线程,新任务将被拒绝。

  2. 无界队列策略(Unbounded queue): 无界队列策略使用一个没有容量限制的阻塞队列存储任务。在这种策略下,将一直接收新的任务,直到系统资源耗尽。这意味着即使线程池中的线程数达到上限,新提交的任务也会被放入队列中等待执行。这种策略可能导致内存占用过高,因此需要特别关注系统资源的管理。

  3. 有界队列策略(Bounded queue): 有界队列策略使用一个具有固定容量的阻塞队列来存储任务。当线程池的工作线程数达到上限时,新提交的任务将被放入队列中等待执行。如果队列已满,后续的任务将根据线程池的拒绝策略进行处理,例如抛出异常或者执行预定义的拒绝逻辑。

  4. 优先级队列策略(Priority queue): 优先级队列策略使用一个基于优先级的阻塞队列来存储任务。每个任务都有一个相关联的优先级,高优先级的任务将被优先执行。该策略可以根据任务的优先级来决定任务的执行顺序,而不是按照任务的提交顺序。这对于一些具有紧急性或重要性要求的任务调度场景非常有用。

 

第七个策略,拒绝策略,可以根据业务需求选择,也可以自定义

 

以上内容纯属学习~

 

标签:poolExecutor,队列,代码,任务,线程,执行,excutorRunnable,ThreadPoolExecutor
From: https://www.cnblogs.com/qwg-/p/18518130

相关文章

  • 【Linux】巧妙运用<信号量>解决<水果放取问题>(思维导图&代码演示&思路解析)
    前言大家好吖,欢迎来到YY滴Linux系列,热烈欢迎!本章主要内容面向接触过C++的老铁主要内容含:欢迎订阅YY滴C++专栏!更多干货持续更新!以下是传送门!YY的《C++》专栏YY的《C++11》专栏YY的《Linux》专栏YY的《数据结构》专栏YY的《C语言基础》专栏YY的《初学者易错点》......
  • 牛客网刷题(4)(Java之(static)静态变量、静态方法、静态代码块、静态内部类)
    目录一、static关键字。(1)牛客网题目。(2)总结。<1>静态变量。(类变量)1、特点。2、补充与注意。3、代码演示。<2>静态方法1、特点。2、补充与注意。3、代码演示。<3>静态代码块。1、特点。2、补充与注意。3、代码演示。<4>静态内部类。1、特点。2、注意事项。3......
  • uniapp - 详细实现移动端公众号 H5 网页授权登录流程及示例代码,申请测试公众号全流程
    前言Vue版本,请访问这篇文章。在uni-appH5网站平台开发中,详解微信公众号网页接入微信授权登录示例代码,附带申请测试公众号全流程及配置教程,提供前端h5页面公众号网页实现授权登陆并获取用户昵称头像数据的示例源码,用自己项目跑出来的本地局域网IP段就可以拉起公众......
  • Java - 26 代码块
    Java-26代码块[修饰符static]{代码};类似于方法,没有方法名,没有返回,没有参数不用通过对象或类显式调用,而是在加载类或创建对象时隐式调用普通代码块好处构造器的补充机制(减少代码重复冗余),可以做初始化操作/*不管调用哪个构造器创建对象,都会先调用代码块的内......
  • 代码大全2阅读笔记
    代码大全2阅读笔记在当今数字化时代,软件技术日新月异,软件开发的复杂性和规模也在不断增加。为了提升自己在软件开发领域的专业素养和实践能力,我选择阅读《代码大全2》这本书。其全面涵盖软件构建各个方面的内容,吸引我深入探索,期望从中获取宝贵的知识和经验,以更好地应对软件开发......
  • 代码大全阅读笔记
    代码大全2阅读笔记在深入探索软件开发领域的过程中,我邂逅了《代码大全2》这本书。它犹如一座知识的宝库,涵盖了软件构建从基础到高级的各个层面,吸引着我去挖掘其中的智慧。随着软件行业的迅猛发展,项目的复杂度和规模不断提升,我深知提升自身软件开发能力的紧迫性和重要性。而这本......
  • <项目代码>YOLOv8 钢索缺陷检测<目标检测>
     YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如FasterR-CNN),YOLOv8具有更高的检测速度和实时性。1.数据集介绍数据集详情可以参考博主写的文章<数据集>钢索缺陷检测......
  • 什么是无代码?无代码开发平台又是什么?
    无代码是近几年兴起,然后才逐渐出现在大众视野当中。但它最早出现在2014年,由著名研究机构ForresterResearch正式提出,后来经过市场承认以及市场认可阶段,逐步地推出无代码产品和平台,无代码技术开始蓬勃发展,众多供应商们推出,企业开始使用无代码技术加速应用开发与数字化转型,再到后面与......
  • 网安人必备的知识库/漏洞库/代码审计/SRC漏洞挖掘/攻防演练应急响应
    免责声明:本文仅用于技术学习和讨论。请勿使用本文所提供的内容及相关技术从事非法活动,若利用本文提供的内容或工具造成任何直接或间接的后果及损失,均由使用者本人负责,所产生的一切不良后果均与文章作者及本账号无关。再次说明文章所涉及内容,仅供安全研究与教学之用,由于传播、利......
  • 线程池原理
    线程池是一种多线程处理方式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有......