当前位置: 首页 > news >正文

Java中线程池的创建与使用

前言:默认线程池的弊端

在线程池应用中,参考阿里巴巴java开发规范:线程池不允许使用Executors去创建,不允许使用系统默认的线程池,推荐通过ThreadPoolExecutor的方式,这样的处理方式让开发的工程师更加明确>线程池的运行规则,规避资源耗尽的风险。Executors各个方法的弊端:

newFixedThreadPool和newSingleThreadExecutor:主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。

newCachedThreadPool和newScheduledThreadPool:主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

线程池中提交线程的方法,一种是execute()另外一种是submit()

1:2种方法接收的参数不同

2:submit()有返回值,execute()没有

3:submit()方法便于Exception处理

4:execute():提交不需要返回值的任务,无法判断任务是否被执行成功了

5:submit():提交需要放回值的任务;线程会返回Future对象,通过Future的isDone()方法可以判断任务是否执行成功,并且可以通过Future.get()获取返回的值,get方法会阻塞,直到线程的完成

而get(long timeout, TimeUnit unit)会在等待一段时间后返回,这段时间内任务可能没有执行完成

线程池的创建可以分为以下两类

1:通过 ThreadPoolExecutor 手动创建线程池

2:通过 Executors 执行器自动创建线程池

1:FixedThreadPool

创建一个固定大小的线程池,可控制并发线程数。

使用 FixedThreadPool 创建 2 个固定大小的线程池

public static void fixedThreadPool() {// 创建 2 个线程的线程池ExecutorService threadPool = Executors.newFixedThreadPool(2);// 创建任务Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("任务被执行,线程:" + Thread.currentThread().getName());}};threadPool.execute(runnable); threadPool.execute(runnable); threadPool.execute(runnable);threadPool.execute(runnable);
}//如果觉得以上方法比较繁琐,还用使用以下简单的方式来实现线程池的创建和使用:
public static void fixedThreadPool() {// 创建线程池ExecutorService threadPool = Executors.newFixedThreadPool(2);// 执行任务threadPool.execute(() -> {System.out.println("任务被执行,线程:" + Thread.currentThread().getName());});
}

2:CachedThreadPool

创建一个可缓存的线程池,若线程数超过任务所需,那么多余的线程会被缓存一段时间后才被回收,若线程数不够,则会新建线程。有多少任务就动态创建多少线程,线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。CachedThreadPool 是根据短时间的任务量来决定创建的线程数量的,所以它适合短时间内有突发大量任务的处理场景

public static void cachedThreadPool() {// 创建线程池ExecutorService threadPool = Executors.newCachedThreadPool();// 执行任务for (int i = 0; i < 10; i++) {threadPool.execute(() -> {System.out.println("执行任务,线程:" + Thread.currentThread().getName());try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}});}
}

3:SingleThreadExecutor

创建单个线程的线程池,它可以保证线程先进先出的执行顺序

单个线程的线程池相比于线程来说,它的优点有以下 2 个:

1:可以复用线程:即使是单个线程池,也可以复用线程。

2:提供了任务管理功能:单个线程池也拥有任务队列,在任务队列可以存储多个任务,这是线程无法实现的,并且当任务队列满了之后,可以执行拒绝策略,这些都是线程不具备的。

public static void singleThreadExecutor() {// 创建线程池ExecutorService threadPool = Executors.newSingleThreadExecutor();// 执行任务for (int i = 0; i < 10; i++) {final int index = i;threadPool.execute(() -> {System.out.println(index + ":任务被执行");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}});}
}

4:ScheduledThreadPool

创建一个可以执行延迟任务的线程池

执行结果是,任务在 2 秒之后被执行了,实现了延迟 1s 再执行任务

public static void scheduledThreadPool() {// 创建线程池ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);// 添加定时执行任务(2s 后执行)System.out.println("添加任务,时间:" + new Date());threadPool.schedule(() -> {System.out.println("任务被执行,时间:" + new Date());try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {}}, 2, TimeUnit.SECONDS);
}

5:ThreadPoolExecutor

ThreadPoolExecutor 是最原始、也是最推荐的手动创建线程池的方式,它在创建时最多提供 7 个参数可供设置

public static void myThreadPoolExecutor() {// 创建线程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, //corePoolSize 核心线程数10, //MaxPS  最大线程数100, //keepAliveTime  存活时间TimeUnit.SECONDS, //TimeUnit  时间单位new LinkedBlockingQueue<>(10),//BlockingQueue  任务队列Executors.defaultThreadFactory(),//ThreadFactory  线程工厂new ThreadPoolExecutor.DiscardPolicy());//RejectStrategy  拒绝策略// 执行任务
}
corePoolSize:线程池核心线程数(平时保留的线程数)
maximumPoolSize:线程池最大线程数(当workQueue都放不下时,启动新线程,最大线程数)
keepAliveTime:超出corePoolSize数量的线程的保留时间。
unit:keepAliveTime单位
workQueue:阻塞队列,存放来不及执行的线程
ArrayBlockingQueue:构造函数一定要传大小
LinkedBlockingQueue:构造函数不传大小会默认为(Integer.MAX_VALUE ),当大量请求任务时,容易造成 内存耗尽。
SynchronousQueue:同步队列,一个没有存储空间的阻塞队列 ,将任务同步交付给工作线程。
PriorityBlockingQueue : 优先队列
threadFactory:线程工厂
handler:饱和策略,当工作队列中的任务已到达最大限制,并且线程池中的线程数量也达到最大限制,这时如果有新任务提交进来,该如何处理呢。这里的拒绝策略,就是解决这个问题的,jdk中提供了4中拒绝策略
AbortPolicy(默认):该策略下,直接丢弃任务,并抛出RejectedExecutionException异常
CallerRunsPolicy:用调用者的线程执行任务,该策略下,在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务
DiscardOldestPolicy:该策略下,抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
DiscardPolicy:该策略下,直接丢弃任务,什么都不做

相关文章:

Java中线程池的创建与使用

前言&#xff1a;默认线程池的弊端在线程池应用中&#xff0c;参考阿里巴巴java开发规范&#xff1a;线程池不允许使用Executors去创建&#xff0c;不允许使用系统默认的线程池&#xff0c;推荐通过ThreadPoolExecutor的方式&#xff0c;这样的处理方式让开发的工程师更加明确&…...

关于HashMap与OkHttp的使用

写了一个okhttp的post请求方法&#xff0c;添加参数很麻烦&#xff0c;需要封装&#xff1a; //post请求public static void sendOkHttpRequestPost(String address , Callback callback) {OkHttpClient client new OkHttpClient();// 创建表单参数RequestBodyRequestBody fo…...

华为OD机试 - 单词倒序(C 语言解题)【独家】

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:单词倒序…...

搭建Samba服务器

搭建Samba服务器 文章目录搭建Samba服务器samba安装安装命令配置-ubuntu侧为samba服务器创建一个共享目录share创建使用该共享文件夹的账号修改samba服务器配置文件重启samba服务windows创建映射1.点击映射网络驱动器2.输入Ubuntu中的ip地址及其用户信息3.输入用户信息及其密码…...

Matlab进阶绘图第5期—风玫瑰图(WindRose)

风玫瑰图(Wind rose diagram)是一种特殊的极坐标堆叠图/统计直方图&#xff0c;其能够直观地表示某个地区一段时期内风向、风速的发生频率。 风玫瑰图在建筑规划、环保、风力发电、消防、石油站设计、海洋气候分析等领域都有重要作用&#xff0c;所以在一些顶级期刊中也能够看…...

【SQL开发实战技巧】系列(二十四):数仓报表场景☞通过执行计划详解”行转列”,”列转行”是如何实现的

系列文章目录 【SQL开发实战技巧】系列&#xff08;一&#xff09;:关于SQL不得不说的那些事 【SQL开发实战技巧】系列&#xff08;二&#xff09;&#xff1a;简单单表查询 【SQL开发实战技巧】系列&#xff08;三&#xff09;&#xff1a;SQL排序的那些事 【SQL开发实战技巧…...

XILINX AXI总线学习

AXI介绍什么是AXI&#xff1f;AXI&#xff08;高级可扩展接口&#xff09;&#xff0c;是ARM AMBA的一部分&#xff1b;AMBA:高级微控制器总线架构&#xff1b;是1996年首次引入的一组微控制器总线&#xff1b;开放的片内互联的总线标准&#xff0c;能在多主机设计中实现多个控…...

2022CCPC女生赛(补题)(A,C,E,G,H,I)

迟了好久的补题&#xff0c;&#xff0c;现在真想把当时赛时的我拉出来捶一拳排序大致按照题目难度。C. 测量学思路&#xff1a;直接循环遍历判断即可&#xff0c;注意角度要和2π取个最小值。AC Code&#xff1a;#include <bits/stdc.h>typedef long long ll; const int…...

【Nginx】Nginx的安装配置

环境说明系统&#xff1a;Centos 7一、编译安装Nginx官网下载地址nginx: download#安装依赖 [rootnginx nginx-1.22.1]# yum install gcc pcre pcre-devel zlib zlib-devel -y #从官网下载Nginx安装包&#xff0c;并进行解压、编译、安装 [rootnginx ~]# wget https://nginx.or…...

数学小课堂:统计时有效地筛选数据

文章目录引言I 被爆冷门的原因II 统计时有效地筛选数据2.1 统计数据的常见问题2.2 大数据的特征2.3 有效筛选数据的原则引言 在博弈论中很多结果有发生的概率&#xff0c;而概率这件事只是估计出来的&#xff0c;并不准确。因此&#xff0c;一旦加入博弈的选手多了之后&#x…...

MySQL安装优化

hello&#xff0c;大家好&#xff0c;我是小鱼 本文主要通过针对 MySQL Server&#xff08;mysqld&#xff09;相关实现机制的分析&#xff0c;得到一些相应的优化建议。主要 涉及 MySQL 的安装以及相关参数设置的优化&#xff0c;但不包括 mysqld 之外的比如存储引擎相关的参…...

RocketMQ系列开篇

RocketMQ系列开篇 今天开始学习RocketMQ相关系列源码。我会带着自己的目的去学习源码。所以不会像一般的技术博客一样&#xff0c;写一个完整的流程&#xff0c;介绍每一步干了啥。而是提出一个问题&#xff0c;然后去看代码里面是怎么实现的。说明一下&#xff0c;本次系列我…...

logback无法删除太久远的日志文件?logback删除日志文件源码分析

logback无法删除太久远的日志文件&#xff1f;logback删除日志文件源码分析 最近发现logback配置滚动日志&#xff0c;但是本地日志文件甚至还有2年前的日志文件&#xff0c;服务器是却是正常的&#xff01; 网上搜索了一波没有发现&#xff0c;只找到说不能删除太久远的旧日志…...

【MyBatis-Plus】基于@Version注解的乐观锁实现

引入mybatis-plus依赖&#xff0c;注意这里的版本要求 since 3.4.0&#xff1b;&#xff08;3.4.1,3.4.2已测&#xff09; 3.2.0肯定是不支持的&#xff0c;无法引入MybatisPlusInterceptor&#xff1b; 乐观锁 当要更新一条记录的时候&#xff0c;希望这条记录没有被别人更新…...

ubuntu20.04搭建detectron2环境

Ubuntu22.04安装Cuda11.3 Linux下驱动安装 # 以下命令按顺序执行 sudo apt update && sudo apt upgrade -y # or sudo apt update # 查看显卡信息 ubuntu-drivers devices sudo ubuntu-drivers autoinstall # or sudo apt install nvidia-driver-510 reboot nvidia-s…...

Navicate远程连接Linux上docker安装的MySQL容器

Navicate远程连接Linux上docker安装的MySQL容器失败 来自&#xff1a;https://bluebeastmight.github.io/ 问题描述&#xff1a;windows端的navicat远程连接不上Linux上docker安装的mysql&#xff08;5.7版本&#xff09;容器&#xff0c;错误代码10060 标注&#xff1a; 1、…...

基于Jetson NX的模型部署

系统安装 系统安装过程分为3步&#xff1a; 下载必要的软件及镜像 Jetson Nano Developer Kit SD卡映像 https://developer.nvidia.com/jetson-nano-sd-card-image Windows版SD存储卡格式化程序 https://www.sdcard.org/downloads/formatter_4/eula_windows/ 镜像烧录工具…...

【PaddlePaddle onnx】PaddlePaddle导出ONNX及模型可视化教程

文章目录1 背景介绍2 实验环境3 paddle.onnx.export函数简介4 代码实操4.1 PaddlePaddle与ONNX模型导出4.2 ONNX正确性验证4.3 PaddlePaddle与ONNX的一致性检查4.4 多输入的情况5 ONNX模型可视化6 ir_version和opset_version修改7 致谢原文来自于地平线开发者社区&#xff0c;未…...

虹科案例 | 如何可持续的对变压器进行温度监控?

为了延长变压器的使用寿命&#xff0c;需要一个测量系统来监测内部整个绕组区域的温度。它必须明确温度升高发生的位置及其强度。您可以在此处了解为什么会这样以及如何在实践中实施? PART 1 变压器多点测温问题 变压器的工作温度越高&#xff0c;使用寿命越短。这里主要存在…...

Go之入门(特性、变量、常量、数据类型)

一、Go语言特性 语法简单并发性。Go语言引入了协程goroutine&#xff0c;实现了并发编程内存分配。Go语言为了解决高并发下内存的分配和管理&#xff0c;选择了tcmalloc进行内存分配&#xff08;为了并发设计的高性能内存分配组件&#xff0c;使用cache为当前线程提供无锁分配…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...