四种封装 ThreadPoolExecutor 的线程池的使用以及直接使用 ThreadPoolExecutor ,优缺点分析

池化思想:线程池、字符串常量池、数据库连接池
提高资源的利用率
下面是手动创建线程和执行任务过程,可见挺麻烦的,而且线程利用率不高。

  1. 手动创建线程对象
  2. 执行任务
  3. 执行完毕,释放线程对象

线程池的优点:

  • 提高线程的利用率
  • 提高程序的响应速度
  • 便于统一管理线程对象
  • 可以控制最大并发数
package chapter09;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;public class Java05_Thread_Pool {public static void main(String[] args) {// TODO 线程 - 线程池// 所谓线程池,其实就是线程对象的容器// 可以根据需要,在启动时,创建一个或多个线程对象// 快速创建线程池的4种比较常见的方法// 它们都是对 ThreadPoolExecutor 的封装,那必然无法满足更复杂,更需要自定义功能的需求场景// 1. 创建固定数量的线程对象//    ExecutorService是线程服务对象ExecutorService executorService = Executors.newFixedThreadPool(3);// 2. 根据需求动态创建线程, 创建的线程可以重复使用,只是当目前线程不够了他会动态增加线程executorService = Executors.newCachedThreadPool();// 3. 单一线程executorService = Executors.newSingleThreadExecutor();// 4. 定时调度线程, 线程有3个,但是线程在什么时候执行我们可以去定义他executorService = Executors.newScheduledThreadPool(3);// 使用submit提交任务for (int i = 0; i < 5; i++) {executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println("submit方式 " + Thread.currentThread().getName());}});}// 使用execute提交任务for (int i = 0; i < 5; i++) {executorService.execute(new Runnable() {@Overridepublic void run() {System.out.println("execute方式 " + Thread.currentThread().getName());}});}executorService.shutdown(); // 关闭线程池// 如果你需要更多的控制和自定义选项,使用 ThreadPoolExecutor 可以满足更复杂的需求// 使用银行柜台服务的场景来解释 ThreadPoolExecutor 的每个参数ExecutorService executorService1 = new ThreadPoolExecutor(3,  // corePoolSize-核心线程数,即银行的初始柜台数,// 具体来说:银行一开始有 3 个柜台,每个柜台有一个员工(线程)在处理客户(任务)。这些柜台是常驻的,即使没有客户时也不会关闭5,  // maximumPoolSize-最大线程数,即银行在高峰期能开设的最大柜台数量// 在客户数量增加的时候,银行可以最多开设 5 个柜台来处理客户。超过这个数量的客户需要排队等候1L, // keepAliveTime-非核心线程的存活时间// 如果一个临时增加的柜台(超过核心柜台数的部分)空闲了 1 秒钟,那么这个柜台就会关闭(线程会被回收)。// 这就像银行在高峰期增加了柜台,但在高峰期过后,临时柜台会在短时间内关闭,以节省资源TimeUnit.SECONDS, // keepAliveTime's unit-存活时间的单位// 这里的单位是秒,表示非核心线程在空闲 1 秒后会被关闭,跟上面的 keepAliveTime 配合使用new ArrayBlockingQueue<>(3), // workQueue-等待队列,用于存放等待处理的任务// 假如银行有一个容量为 3 的等候区(队列),当所有柜台都在忙碌时,新的客户会在这个等候区等待。// 如果等候区也满了,那么将会触发下面handler的策略(下面是 拒绝策略)Executors.defaultThreadFactory(), // threadFactory-线程工厂,用于创建新线程// 这是一个工厂模式,负责为银行创建新的柜台(线程)。// Executors.defaultThreadFactory() 是默认的实现,它会创建一个新的线程来处理任务。new ThreadPoolExecutor.AbortPolicy() // handler-当线程池和等待队列都满了时如何处理新任务的策略// 如果所有的柜台(线程)和等候区(队列)都满了,再来新的客户时会执行拒绝策略。// AbortPolicy 会抛出 RejectedExecutionException,就像银行告诉新来的客户“我们现在无法处理您的请求,请稍后再试”。);/*ExecutorService类对象可以使用两种方法向线程池提交任务:submit 和 execute。execute 方法用于提交不需要返回结果的任务。它是 Executor 接口中的方法返回类型: void。execute 方法不返回任何结果。异常处理: 如果任务在执行过程中抛出未经检查的异常,该异常将直接传播到调用者所在的线程。适用场景: 适用于不需要返回结果的任务,比如简单的异步执行任务。submit 方法用于提交有返回结果的任务。它是 ExecutorService 接口中的方法。返回类型: Future<V>。submit 方法返回一个 Future 对象,可以通过该对象获取任务的执行结果或取消任务。异常处理: 如果任务在执行过程中抛出未经检查的异常,该异常将被捕获,并存储在返回的 Future 对象中。调用 Future.get() 方法时,会抛出 ExecutionException。适用场景: 适用于需要返回结果的任务,比如计算任务,或者你需要检查任务是否成功完成。通过这两种方法,你可以根据任务的具体需求来选择合适的提交方式。如果任务需要返回结果或需要检查执行状态,使用 submit;如果任务只是执行,不需要返回结果,使用 execute。*/List<Future<Integer>> futureList = new ArrayList<>();// 使用submit提交任务,并且改变需要执行的Runnable任务来看看线程池有什么变化情况// 任务数i在6个以内,executorService1指向的线程池只开3个线程// 7个任务开四个线程, 8个任务开五个线程// 9个任务直接 Exception in thread "main" java.util.concurrent.RejectedExecutionException// 解释:// 3个任务:直接全部给到三个核心线程处理// 4~6个任务:三个核心线程处理其中3个任务,剩下的任务进入等待队列// 7个任务:三个核心线程处理其中3个任务,等待队列存放3个任务,那还剩下1个任务就交给非核心线程处理(增设了一个额外的线程)// 8个任务:三个核心线程处理其中3个任务,等待队列存放3个任务,那还剩下2个任务就交给两个非核心线程处理(增设了两个额外的线程)// 9个任务:三个核心线程处理其中3个任务,等待队列存放3个任务,那还剩下3个任务,但是最大线程数是5个,// 也就是说再多只能在三个核心线程的基础上再增设两个额外的线程,但是也不够处理剩下的3个任务// 或者说 最大线程数大小 5 + 等待队列大小 3 = 8 < 任务所需的线程数 9for (int i = 1; i <= 3; i++) {int taskId = i;Future<Integer> future = executorService1.submit(new Callable() {@Overridepublic Integer call() {System.out.println(Thread.currentThread().getName() + "正在处理业务" + taskId);return taskId;}});futureList.add(future);}Iterator<Future<Integer>> it = futureList.iterator();while (it.hasNext()) {Future<Integer> future = it.next();try {Integer result = future.get();System.out.println("Result: " + result);} catch (InterruptedException e) {throw new RuntimeException(e);} catch (ExecutionException e) {throw new RuntimeException(e);}}// 使用execute方式提交任务for (int i = 1; i <= 9; i++) {int taskId = i;executorService1.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "正在处理业务" + taskId);}});}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Static关键字的用法详解

Static关键字的用法详解 1、Static修饰内部类2、Static修饰方法3、Static修饰变量4、Static修饰代码块5、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java编程语言中&#xff0c;static是一个关键字&#xff0c;它可以用于多种上…

React+TS前台项目实战(二十三)-- 基于属性自定义数值显示组件Decimal封装

文章目录 前言Decimal组件1. 功能分析2. 代码详细注释3. 使用方式4. 效果展示 总结 前言 今天要封装的Decimal 组件&#xff0c;是通过传入的属性进行定制化显示数值&#xff0c;在渲染时&#xff0c;会根据不同的情况显示整数部分、小数部分和单位&#xff0c;支持自定义样式…

shell脚本awk中使用for循环

今天想使用shell脚本处理一ini文件下的ip地址&#xff0c;也就是INTRANET&#xff0c;前面的ip地址&#xff0c;折腾挺久。文件格式如下&#xff1a; 正确代码&#xff1a; grep -E INTRANET /home/aaaa/bbbb/hostinfo.ini | awk -F , {for(i1; i<NF; i) if($i~"INT…

全国现状建筑数据,选中范围即可查询下载,富含建筑物位置、层数、建筑物功能、名称地址等信息!

今天分享的是一个绘制范围即可下载范围内的建筑数据下载工具&#xff0c;内含高质量建筑数据数据源&#xff0c;助力场地建设规模一目了然。 数据可视化&#xff1a; 建筑物位置、层数、建筑轮廓地图可见&#xff0c;辅助分析。 数据字段&#xff1a; 建筑高度、层数、基地面…

2024年度最佳大型语言模型(LLMs)汇总大全

大型语言模型(LLMs)是人工智能文本处理的主要类型&#xff0c;也现在最流行的人工智能应用形态。ChatGPT是迄今为止最著名的使用LLM的工具&#xff0c;它由OpenAI的GPT模型的特别调整版本提供动力。但还有许多其他聊天机器人和文本生成器&#xff0c;包括从Google Bard和Anthro…

加速度传感器信号处理注意事项

1 传感器分类 对于压电式压力传感器而言&#xff0c;输出信号是最重要的选择标准之一。压电式压力传感器与电子电路相连&#xff0c;电子电路将传感器产生的电荷成比例转换为电压。 如果选用外部设备&#xff08;电荷放大器&#xff09;充当电子元件&#xff0c;则称其为电…

【毛发教程】使用 Maya、XGen 和虚幻引擎创建马尾辫发型

Malte Resenberger-Loosmann是国外一名首席艺术家&#xff0c;他负责指导整个艺术部门来制作独立游戏项目中的3D建模。在本文中&#xff0c;Loosmann展示了马尾辫发型背后的工作流程&#xff0c;分享了 Maya 和虚幻引擎中的场景设置&#xff0c;并解释了 GS CurveTools 如何帮助…

基于IIS的Windows系统Django项目本地部署

参考&#xff1a; 1. 基于Windows平台的Django本地部署和腾讯云服务器上部署&#xff08;1&#xff09;_如何在服务器上发布部署django程序 csdn-CSDN博客 2.Windows server iis部署Django详细操作 - Django中文 - 博客园 (cnblogs.com) 3.在IIS中部署pythonDjango项目时出…

Python: 分块读取文本文件

在处理大文件时&#xff0c;逐行或分块读取文件是很常见的需求。下面是几种常见的方法&#xff0c;用于在 Python 中分块读取文本文件&#xff1a; 1、问题背景 如何分块读取一个较大的文本文件&#xff0c;并提取出特定的信息&#xff1f; 问题描述: fopen(blank.txt,r) quot…

使用任意电脑通过内网穿透生成的公网地址远程SSH连接本地Windows电脑

文章目录 前言1. Windows安装SSH服务2. Windows本地连接测试3. Windows安装Cpolar工具4. 配置SSH公网地址5. 远程SSH 连接测试6. 固定SSH公网地址7. 固定SSH地址测试 前言 在当今的数字化转型时代&#xff0c;远程连接和管理计算机已成为日常工作中不可或缺的一部分。对于Wind…

微信小程序留言板1

wxml&#xff1a; <view class"view2"> <text class"test1">留言&#xff1a;</text><input type"text" class"input1" bindinput"ipt"/><button class"btn" bindtap"btn"…

spring mvc学习

第四章 Spring MVC 第一节 Spring MVC 简介 1. Spring MVC SpringMVC是一个Java 开源框架&#xff0c; 是Spring Framework生态中的一个独立模块&#xff0c;它基于 Spring 实现了Web MVC&#xff08;数据、业务与展现&#xff09;设计模式的请求驱动类型的轻量级Web框架&am…

「媒体邀约」全国巡演,多地推介会,如何做好媒体宣传

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体宣传加速季&#xff0c;100万补贴享不停&#xff0c;一手媒体资源&#xff0c;全国100城线下落地执行。详情请联系胡老师。 我们在做多地活动的时候&#xff0c;比如演唱会&#xff…

【LeetCode】十一、滑动窗口:长度最小的子数组 + 定长子串的元音最大数目

文章目录 1、滑动窗口2、leetcode209&#xff1a;长度最小的子数组3、leetcode1456&#xff1a;定长子串中元音的最大数目 1、滑动窗口 如下&#xff0c;有一个数组&#xff0c;现三个元素为一组&#xff0c;求最大的和&#xff0c;自然可以while循环实现&#xff1a;i 、i1、…

数据结构(Java):迭代器遍历【底层源码解析】

1、引言 我们知道&#xff0c;对于List系列集合&#xff0c;添加的元素是有序、可重复、有索引的&#xff1b;而对于Set系列集合&#xff0c;添加的元素是无序、不重复、无索引的。 那么使用for循环通过下标来对Set系列集合进行遍历&#xff0c;那显然是不行的。 迭代器就可…

51单片机-让一个LED灯闪烁、流水灯(涉及:自定义单片机的延迟时间)

目录 设置单片机的延迟&#xff08;睡眠&#xff09;函数查看单片机的时钟频率设置系统频率、定时长度、指令集 完整代码生成HEX文件下载HEX文件到单片机流水灯代码 (自定义延迟时间) 设置单片机的延迟&#xff08;睡眠&#xff09;函数 查看单片机的时钟频率 检测前单片机必…

JVM的五大内存区域

JVM的五大内存区域 JVM内存区域最粗略的划分可以分为 堆 和 栈 &#xff0c;当然&#xff0c;按照虚拟机规范&#xff0c;可以划分为以下几个区域&#xff1a; JVM内存分为线程独享区和线程共享区&#xff0c; 其中 方法区 和 堆 是线程共享区&#xff0c; 虚拟机栈, 本地方法…

延边幼儿园1*3 OLED柔性屏翻页一体机安装项目

一、产品介绍 本次项目在吉林省延吉市延边幼儿园内&#xff0c;引入了先进的55寸1*3 OLED柔性屏翻页一体机。该设备集高清显示、灵活翻页、互动教学等功能于一体&#xff0c;专为现代幼儿教育环境设计&#xff0c;旨在通过科技手段提升教学质量&#xff0c;丰富教学手段&#x…

1.1.2数据结构的三要素

一.数据结构的三要素 数据结构这门课着重关注的是数据元素之间的关系&#xff0c;和对这些数据元素的操作&#xff0c;而不关心具体的数据项内容 。 1.逻辑结构 &#xff08;1&#xff09;集合结构 &#xff08;2&#xff09;线性结构 数据元素之间是一对一的关系。除了第一个…

MongoDB-社区版-本地安装

系统&#xff1a;win10 1. 下载server:Download MongoDB Community Server | MongoDB 我选的zip包 2. 下载shell&#xff1a;MongoDB Shell Download | MongoDB 我选的zip包 3. 启动server 4. 启动shell, 完成