Java线程池,看这一篇足够

目录一览

  • Java线程池
    • 1. Executors提供6个线程池快捷创建方式
    • 2. ThreadPoolExecutor的7大参数
    • 3. 自定义线程池

Java线程池

上一篇《@Async注解的注意事项》说到@Async注解要配合自定义线程池一起使用,这一节说下Java的线程池。

1. Executors提供6个线程池快捷创建方式

    public static void main(String[] args) {
        // 定长线程池,核心线程数和最大线程数一致
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 缓存线程池,核心线程数为0,最大线程数Integer最大值,线程存活时间超长
        ExecutorService executorService1 = Executors.newCachedThreadPool();
        // 定时线程池,可以设置执行时间
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        // 单线程线程池,核心线程和最大线程数都为1
        ExecutorService executorService2 = Executors.newSingleThreadExecutor();
        // 核心线程数为1的定时线程池,可以执行定时任务
        ScheduledExecutorService scheduledExecutorService1 = Executors.newSingleThreadScheduledExecutor();
        // 窃取线程池,并行执行线程,依赖cpu个数
        ExecutorService executorService3 = Executors.newWorkStealingPool(3);
    }

通过调试依次看下各个线程池的实际参数

newFixedThreadPool,定长线程池

在这里插入图片描述

可见,corePoolSize和maxinumPoolSize数是一样的,说明线程不会销毁,且不会动态扩容。灵活性较差

newCachedThreadPool,缓存线程池

在这里插入图片描述

corePoolSize为0,maxinumPoolSize为max integer,重点是keepAliveTime为600亿毫秒,线程一旦创建几乎不会销毁,容易造成OOM。

newScheduledThreadPool,定时线程池

在这里插入图片描述

maxinumPoolSize为max integer,可能造成OOM。主要特点是创建的ScheduledThreadPoolExecutor实现了ScheduledExecutorService接口,其中的schedule等方法可以设置定时执行任务。

在这里插入图片描述

newSingleThreadExecutor,单线程线程池

在这里插入图片描述

corePoolSize和maxinumPoolSize都为1,说明单个线程执行任务,未执行的任务只能堆叠在workQueue。

newSingleThreadScheduledExecutor,单线程定时线程池

在这里插入图片描述

事实上就是newScheduledThreadPool,只是corePoolSize设置为1

在这里插入图片描述

newWorkStealingPool,窃取线程池

在这里插入图片描述

这个线程池比较特殊,它是java8才提出来的,不是通过ThreadPoolExecutor创建,没有corePoolSize等参数。且线程是并行进行的,即依赖处理器进行。

我觉得下面这篇文章对我有帮助,可以阅读一下

WorkStealingPool的使用简析

以上就是通过Executors创建的6种线程池

2. ThreadPoolExecutor的7大参数

通过Executors创建的6种线程池,除了java8提出的newWorkStealingPool,其他都是直接或者间接(子类)创建

ThreadPoolExecutor类实现的。

在这里插入图片描述

ThreadPoolExecutor主要有7大参数

在这里插入图片描述

  • corePoolSize,核心线程数,线程池默认线程数,线程池创建完成时,会初始化的线程数量,当有任务进来时,通过调度线程执行任务。

  • maxinumPoolSize,最大线程数,最大线程数必须大于或等于核心线程数,核心线程正在执行任务,而有新任务进来,且当下线程数量未达到最大线程数时,会新建线程放进线程池,再用新线程执行任务。

  • keepAliveTime,存活时间,除开核心线程外的线程,也就是大于核心线程数的部分线程,如果没有任务调度该线程执行,当该线程的空闲时间达到keepALiveTime值时,会被销毁。

  • unit,时间单位,keepAliveTime的单位,一般为毫秒

  • workQueue,工作队列,也称为等待队列,任务调用时先进入工作队列,然后等待空闲线程调度。

  • threadFactory,线程工厂,指定创建线程的方式,通过线程工厂创建和销毁线程,一般使用 Executors.defaultThreadFactory() 足够,不用自定义创建该工厂类。

  • handler,拒绝策略,该类主要针对当工作队列满了之后,新的任务进来,拒绝存放在工作队列,执行的操作。其中rejectedExecution方法就是拒绝的处理方法。

    ThreadPoolExecutor提供了默认四种拒绝策略。(如果不理解可以看下源码,很简单的逻辑)

    • CallerRunsPolicy,从哪来,往哪走,由提交执行任务。
    • AbortPolicy,直接报异常
    • DiscardPolicy,什么都不做,rejectedExecution这个方法直接留空,哈哈
    • DiscardOldestPolicy,workQueue最后的任务直接踢掉,然后插入本任务

3. 自定义线程池

在阿里开发手册中明令禁止使用Executors创建线程池,通过以上第一点介绍的6种线程池可以看出,Executors提供的线程池中有些maxinumPoolSize设置为max integer,或者workQueue的容量设置为max integer(如newFixedThreadPool和newSingleThreadExecutor中,workQueue使用LinkedBlockingQueue,其size为Integer.MAX_VALUE),这存在内存溢出风险。

因而在实际开发中,最好自定义线程池。只需要实例化ThreadPoolExecutor类即可,所以自定义线程池实质上就是配置好上述第二点中的7大参数。

    public ThreadPoolExecutor myThreadExecutor(){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                10,
                20,
                60,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        return threadPoolExecutor;
    }

最后,@Async配合自定义线程池使用,可以看我上篇文章《@Async注解的注意事项》

至此,全篇结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/343568.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第八篇 交叉编译华为云Iot SDK到Orangepi3B

本篇主要内容&#xff1a; 一、交叉编译华为云Iot SDK依赖1.宿主机安装交叉编译工具链&#xff08;1&#xff09;选择下载交叉编译工具链&#xff08;2&#xff09;解压、添加环境变量、重启2.交叉编译依赖库&#xff08;0&#xff09; 准备工作&#xff08;1&#xff09; 交叉…

MySQL>基础sql语句

阅读目录 1.进入数据库2.数据库操作&#xff08;增删改查用&#xff09;3.表操作(增删改查)4.语句操作(增删改查) 回到顶部 1.进入数据库 打开终端,输入&#xff1a; /usr/local/mysql/bin/mysql -uroot -p回车 输入密码&#xff1a; 回到顶部 2.数据库操作&#xff08;增…

RabbitMQ环境配置

文章目录 安装Erlang安装RabbitMQ 安装Erlang 下载地址&#xff1a;http://erlang.org/download/otp_win64_25.3.2.7.exe 安装RabbitMQ 下载地址&#xff1a;https://www.rabbitmq.com/install-windows.html 进入RabbitMQ安装目录下的sbin目录 输入以下命令启动管理功能 …

Java 设计者模式以及与Spring关系(七) 命令和迭代器模式

简介: 本文是个系列一次会出两个设计者模式作用&#xff0c;如果有关联就三个&#xff0c;除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道设计者模式有3类23种设计模式&#xff0c;标红是特别重要的设计者模式建议都会&#xff0c;而且熟读于心&#…

Django开发_17_表单类

一、介绍 为了简化前端form表单代码 二、步骤 &#xff08;一&#xff09;创建form.py 创建一个表单类 from django import formsclass RegisterForm(forms.Form):reg_name forms.CharField(max_length10, label用户名)reg_pwd forms.CharField(max_length20, label密码…

python Seq2Seq模型源码实战,超详细Encoder-Decoder模型解析实战;早期机器翻译模型源码demo

1.Seq2Seq&#xff08;Encoder-Decoder&#xff09;模型简介 Seq2Seq&#xff08;Encoder-Decoder&#xff09;模型是一种常用于序列到序列&#xff08;sequence-to-sequence&#xff09;任务的深度学习模型。它由两个主要的组件组成&#xff1a;编码器&#xff08;Encoder&am…

顶顶通呼叫中心中间件机器人压力测试配置(mod_cti基于FreeSWITCH)

介绍 顶顶通呼叫中心中间件机器人压力测试(mod_cit基于FreeSWITCH) 一、配置acl.conf 打开ccadmin-》点击配置文件-》点击acl.conf-》我这里是已经配置好了的&#xff0c;这里的192.168.31.145是我自己的内网IP&#xff0c;你们还需要自行修改 二、配置线路 打开ccadmin-&g…

社区分享|百果园选择DataEase搭档蜜蜂微搭实现企业数据应用一体化

百果园&#xff0c;全称为深圳百果园实业&#xff08;集团&#xff09;股份有限公司&#xff0c;2001年12月成立于深圳&#xff0c;2002年开出中国第一家水果专卖店。截至2022年11月&#xff0c;百果园全国门店数量超过5600家&#xff0c;遍布全国140多个城市&#xff0c;消费会…

实现单链表的增删改查

实现单链表的增删改查的功能&#xff1a;头部插入删除/尾部插入删除&#xff0c;查找&#xff0c;在指定位置之前插入数据&#xff0c;删除pos节点&#xff0c;在指定位置之后插入数据&#xff0c;删除pos之后的节点&#xff0c;销毁链表。 SListNode.h #pragma once #includ…

工程化代码管理高频面试题

1. git常用命令以及工作中都怎么工作 git init 初始化仓库 ​ git status 查看当前各个区域的代码状态。 ​ git log查看commit记录 ​ git reflog查看完整记录 ​ git add 添加工作区代码到暂存区 ​ Git commit 暂存区代码的提交 ​ git reset 代码的版本回退 ​ git stash …

Python中的open与JSON的使用

目录 1 使用 open 函数进行文件操作 2 使用 json 模块进行 JSON 数据处理&#xff1a; 2.1 写入JSON 文件 2.2 读取JSON 文件 在 Python 中&#xff0c;open 函数和 json 模块常用于文件的读写和 JSON 数据的处理。 1 使用 open 函数进行文件操作 open 函数用于打开文件…

docker安装Rabbitmq教程(详细图文)

目录 1.下载Rabbitmq的镜像 2.创建并运行rabbitmq容器 3.启动web客户端 4.访问rabbitmq的微博客户端 5.遇到的问题 问题描述&#xff1a;在rabbitmq的web客户端发现界面会弹出如下提示框Stats in management UI are disabled on this node 解决方法 &#xff08;1&#…

【JAVA语言-第14话】集合框架(一)——Collection集合,迭代器,增强for,泛型

目录 集合框架 1.1 概述 1.2 集合和数组的区别 1.3 Collection集合 1.3.1 概述 1.3.2 常用方法 1.4 迭代器 1.4.1 概述 1.4.2 常用方法 1.4.3 使用步骤 1.5 增强for循环 1.5.1 概述 1.5.2 使用 1.6 泛型 1.6.1 概述 1.6.2 使用泛型的利弊 1.6.2.1 好处 1…

06章【Eclipse与异常处理】

Eclipse开发环境使用入门 Eclipse开发环境使用入门 下载安装配置环境Eclipse入门 异常处理 异常 异常是阻止当前方法或作用域继续执行的问题&#xff0c;在程序中导致程序中断运行的一些指令 try与catch关键字 在程序中出现异常&#xff0c;就必须进行处理&#xff0c;处理格…

vue的模板语法-指令-事件绑定-条件渲染

VSCode代码片段生成 我们在前面练习Vue的过程中&#xff0c;有些代码片段是需要经常写的&#xff0c;我们再VSCode中我们可以生成一个代码片段&#xff0c;方便我们快速生成。 VSCode中的代码片段有固定的格式&#xff0c;所以我们一般会借助于一个在线工具来完成。 具体的步…

Shell脚本 2

一、变量 变量来源于数学&#xff0c;是计算机语言中能储存计算结果或能表示值的抽象概念。 保存将来会变化的数据&#xff0c;即使数据变化&#xff0c;直接调用变量即可&#xff0c;各种 Shell 环境中都使用到了“变量”的概念。Shell 变量用来存放系统和用户需要使用的特定…

基于JavaSwing+百度OCR开发的题库管理系统源码+数据库,能够将图片中的文字提取出来,保存题库中

题库管理系统 介绍 具备上传本地图片及截屏功能&#xff0c;并利用百度OCR技术&#xff0c;能够将图片中的文字提取出来&#xff0c;保存题库中&#xff0c;供以后查找。 技术方面&#xff0c;为制作exe可执行文件&#xff0c;该软件将JavaSwing,MybatisPlus,Spring三者进行集…

使用Python合并PPT文件

在日常工作和学习中&#xff0c;我们经常需要处理和管理大量的PPT文件。如果需要将多个PPT文件合并成一个文件&#xff0c;手动操作可能会非常繁琐和耗时。今天&#xff0c;我们将介绍如何使用Python编程语言和wxPython模块创建一个简单的GUI应用程序&#xff0c;来自动合并指定…

力扣精选算法100道——x的平方根(二分查找专题)

x的平方根 首先看到这个题目的时候&#xff0c;我们需要对上一个二分查找专题的题目进行深度理解&#xff0c;然后了解模板&#xff0c;这题是完全利用的上一题的模板知识进行&#xff0c;如果直接看这个题目可能是有点懵的&#xff0c;因为我这里直接利用模板进行解题。力扣…

架构篇14:高性能数据库集群-读写分离

文章目录 读写分离原理复制延迟分配机制小结高性能数据库集群的第一种方式是“读写分离”,其本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力;第二种方式是“分库分表”,既可以分散访问压力,又可以分散存储压力。先来看看“读写分离”,下一篇我们再介绍“分…