首页 > 编程语言 >【Java】线程池配置

【Java】线程池配置

时间:2023-05-31 22:11:37浏览次数:50  
标签:Java 队列 配置 任务 线程 executor new ThreadPoolExecutor

 

先看JUC包自带的一个资源 线程池执行器:

初始化参数如下

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
        corePoolSize, // 核心线程数量
        maximumPoolSize, // 峰值线程数量
        keepAliveTime, // 保留时限,当线程数量超出峰值数量时,保留多久后释放多余的线程资源
        timeUnit, // 时限单位
        synchronousQueue, // 工作队列,存放需要提交给执行器执行的任务
        threadFactory, // 线程工厂
        callerRunsPolicy // 任务拒绝执行处理器(拒绝策略)
);

  

基础参数配置:

峰值上限,保留时限,根据实际业务情况来设置

/**
* 线程数量参数 计算公式参考
* https://www.cnblogs.com/warehouse/p/10810338.html
*/
int cpuCount = Runtime.getRuntime().availableProcessors();

int corePoolSize = 2 * cpuCount; // 核心线程数量(初始化和空闲存留时的线程数量)
int maximumPoolSize = 100; // 最大线程数量 线程占用峰值上限数量
long keepAliveTime = 100; // 保留时长(当前线程数量大于核心数量时保留多久后释放多余线程)
TimeUnit timeUnit = TimeUnit.SECONDS; // 保留时长单位

  

几种工作队列:

/**
* SynchronousQueue队列
*  SynchronousQueue是一个特殊的BlockingQueue
*  它没有容量,每执行一个插入操作就会阻塞,需要再执行一个删除操作才会被唤醒
*  反之每一个删除操作也都要等待对应的插入操作。
*/
SynchronousQueue<Runnable> synchronousQueue = new SynchronousQueue<>();

/**
* ArrayBlockingQueue有界任务队列,若有新的任务需要执行时,线程池会创建新的线程,
* 直到创建的线程数量达到corePoolSize时,则会将新的任务加入到等待队列中。
* 若等待队列已满,即超过ArrayBlockingQueue初始化的容量,则继续创建线程,直到线程数量达到maximumPoolSize设置的最大线程数量,
* 若大于maximumPoolSize,则执行拒绝策略。在这种情况下,线程数量的上限与有界任务队列的状态有直接关系,
* 如果有界队列初始容量较大或者没有达到超负荷的状态,线程数将一直维持在corePoolSize以下,
* 反之当任务队列已满时,则会以maximumPoolSize为最大线程数上限。
*/
ArrayBlockingQueue<Runnable> arrayBlockingQueue = new ArrayBlockingQueue<>(10);

/**
* 无界任务队列,线程池的任务队列可以无限制的添加新的任务,
* 而线程池创建的最大线程数量就是你corePoolSize设置的数量,
* 也就是说在这种情况下maximumPoolSize这个参数是无效的,
* 哪怕你的任务队列中缓存了很多未执行的任务,当线程池的线程数达到corePoolSize后,就不会再增加了;\
* 若后续有新的任务加入,则直接进入队列等待,
* 当使用这种任务队列模式时,一定要注意你任务提交与处理之间的协调与控制,
* 不然会出现队列中的任务由于无法及时处理导致一直增长,直到最后资源耗尽的问题。
*/
LinkedBlockingQueue<Runnable> linkedBlockingQueue = new LinkedBlockingQueue<>();

/**
* PriorityBlockingQueue它其实是一个特殊的无界队列,它其中无论添加了多少个任务,线程池创建的线程数也不会超过corePoolSize的数量
* ,只不过其他队列一般是按照先进先出的规则处理任务,而PriorityBlockingQueue队列可以自定义规则根据任务的优先级顺序先后执行。
*/
PriorityBlockingQueue<Runnable> priorityBlockingQueue = new PriorityBlockingQueue<>();

  

线程工厂使用默认工厂提供:

/**
 * ThreadFactory
 */
ThreadFactory threadFactory = Executors.defaultThreadFactory();

  

拒绝策略一般使用第4个,谁提交谁执行:

/**
 * 当线程需求数量超出预设峰值上限,如何拒绝线程资源获取
 * 1、直接丢弃
 * 2、替换工作队列的最后一个
 * 3、抛异常中断
 * 4、哪个线程提交的任务就让那个线程执行
 * 5、自定义
 */
ThreadPoolExecutor.DiscardPolicy discardPolicy = new ThreadPoolExecutor.DiscardPolicy();
ThreadPoolExecutor.DiscardOldestPolicy discardOldestPolicy = new ThreadPoolExecutor.DiscardOldestPolicy();
ThreadPoolExecutor.AbortPolicy abortPolicy = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor.CallerRunsPolicy callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();
RejectedExecutionHandler handler = (r, executor) -> {
    // 入参一个runnable 和 executor
};

  

Spring封装的线程池:

任务执行器

1、不需要设置队列类型,但是要提供队列长度

2、可以设置线程名称前缀

3、当所有任务执行完毕时,释放线程池资源

4、需要调用初始化方法

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maximumPoolSize);
executor.setQueueCapacity((int)(maximumPoolSize * 1.5D));
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("线程名称前缀");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true); /* 等待所有任务结束后再关闭线程池 */
executor.initialize();

 

要设置手动释放资源,就不要使用Spring注册成Bean配置了,那这个线程池就是临时在业务方法需要调用一下

 

标签:Java,队列,配置,任务,线程,executor,new,ThreadPoolExecutor
From: https://www.cnblogs.com/mindzone/p/17447474.html

相关文章

  • Vagrant编排虚拟机安装与配置
    1.安装VirtualBox与VagrantVirtualBox与Vagrant是支持不通过操作系统的;根据具体操作系统下载对应版本即可。(这里使用windows操作系统搭建)VirtualBoxhttps://www.virtualbox.org/wiki/DownloadsVagranthttps://developer.hashicorp.com/vagrant/downloadsVagrant是没有图形界面的......
  • Redis配置文件
    一、Units单位配置大小单位,开头定义了一些基本度量单位,只支持byte,不支持bit,大小写不敏感二、网络配置默认情况下bind=127.0.0.1只能接收本机的访问请求,不写的情况下,无限制接受任何ip地址的访问生产环境肯定要写你应用服务器的地址;服务器是需要远程访问的,所以需要将其注释掉如......
  • 【随手记录】关于Java字符串长度
    在java当中,在运行期间,字符串的长度是有最大限制的:21亿,也就是4GB;在编译期间,字符串的长度最大为:65534。字符串的内容是由一个字符数组char[]来存储的,由于数组的长度及索引是整数,Integer的最大范围是2^31-1,所以数组的最大长度可以使【0~2^31-1】通过计算是大概4GB=(2*2^31-......
  • Java并发之原子性、可见性和有序性
    1.原子性1.1原子性的定义原子性:原子性即是一个或者多个操作,要么全程执行,并且执行的过程中不被任何因素打断,要么全部不执行。举个例子会更好理解:就像是我们去银行转账的时候,A给B转1000元,如果A的账户减少了1000之后,那么B的账户一定要增加1000。A的账户减钱,B的账户加钱,这两个操作......
  • 会声会影2023新功能有哪些呢?会声会影2023中文旗舰版最低配置要求
    本文转载于:https://blog.csdn.net/weixin_55412152/article/details/130976196会声会影是一款广受欢迎的视频编辑软件,它的最新版本,会声会影2023,已经发布。在这篇文章中,我们将探讨会声会影2023的新功能以及它对视频制作人员的影响。会声会影2023下载地址:https://souurl.cn/3LSPir......
  • Windows 配置 Hadoop and Spark
    一JDK环境配置由于项目用的JDK17,所以单独给Hadoop配了JDK11,建议直接配置JAVA_HOME环境变量为JDK11,因为后面Spark需要用到JAVA_HOME下载JDK11链接:https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html目前Hadoop和Spark兼容JDK11和JDK8单独修改Had......
  • AI实战营第二期 | 环境配置及安装
    AI实战营第二期|环境配置及安装强烈推荐使用mim来管理OpenMMLabrepoOpenMMLabrepo不要mim和pip混用OpenMMLab1.0和OpenMMLab2.0环境分离,不要耦合在一个环境里面以下是比较推荐的初学者配置方式,进阶之后推荐使用软链接模式,详见:OpenMMLab2.0源码阅读和调......
  • Miniconda+Pycharm中虚拟环境配置
    在安装完Miniconda后,win+r打开命令提示符,输入cmd在命令提示符输入conda,出现以下则安装成功;如果输入conda出现“不是内部或外部命令,也不是可运行的程序或批处理文件”,这样的提示说明要手动配置系统环境变量。操作:找到Miniconda的安装路径,找到Scripts,复制文件路径添加到系统path......
  • Java 微服务中的聚合器设计模式示例
    微服务架构中的聚合器设计模式是一种设计模式,用于通过聚合多个独立的微服务的响应来组成一个复杂的服务。它也是与SAGA、CQRS和EventSourcing一起的基本微服务设计模式之一。当客户端请求需要跨多个微服务分布的数据或功能时,此模式是合适的。可以提高系统的性能和可扩展性通过允许......
  • 揭开 JavaScript 事件循环的神秘面纱
    Javascript是一种单线程语言,这意味着它一次只能执行一个任务。但是,它仍然设法同时执行多项任务。它通过使用一些复杂的数据结构给人一种多线程的错觉。为实现这一点,Javascript引擎有一个称为事件循环的重要组件。我们将了解什么是事件循环以及它如何在不阻塞主线程的情况下处理异......