创建线程池

如何创建线程池及处理相应任务

目录

  • 如何创建线程池及处理相应任务
    • 线程池定义
    • 解决的问题(需求)
    • 工作原理
    • 实现线程池创建示意图
    • 重要构造器
    • 创建线程池(ExecutorService)
    • 线程池任务处理
      • 常用API
      • 处理Runnable任务
      • 处理Callable任务
    • 使用工具类(Executors)创建线程池
      • 常用API
      • 应用案例
    • 拓展
      • 思考
      • 任务拒绝策略
    • 参考视频

线程池定义

线程池就是一个可以复用线程的技术,控制线程和任务的数量;线程池中线程长久存在

解决的问题(需求)

用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能,甚至可能会引起系统瘫痪(宕机)

工作原理

  
在这里插入图片描述
  

实现线程池创建示意图

  
在这里插入图片描述
  

重要构造器

  
在这里插入图片描述
 
在这里插入图片描述
  

创建线程池(ExecutorService)

:通过实现类ThreadPoolExecutor()来创建。

package com.xie.thread.pool.demo;import java.util.concurrent.*;/*** 掌握线程池的创建 通过有参构造器创建* */
public class ThreadPoolTest {public static void main(String[] args) {/*** 创建线程池,其各参数具体含义:* 参数一:核心线程数量* 参数二:最大线程数量* 参数三:临时线程存活时间* 参数四:参数三的时间单位* 参数五:任务队列,此处用于 缓存 来自通信管道的任务的* 参数六:线程工厂,用于创建核心线程的* 参数七:任务的拒绝策略,此处用到默认策略,直接拒绝的处理方案,当处理不了时,直接抛异常* */ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());}
}

线程池任务处理


常用API

  
在这里插入图片描述
  

:上面为处理处理Runnable任务的API


  
在这里插入图片描述
  

:上面为处理处理Callable任务的API


处理Runnable任务

Runnable任务类

package com.xie.thread.pool.task1.pojo;/*** Runnable任务类,线程的任务对象模版* */
public class MyRunnable implements Runnable {/*** 执行任务区域(即run方法),描述所要执行的任务*/@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 输出666~~");/** 延迟,模拟业务执行耗时,为了便于观察 */try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}
}

测试

package com.xie.thread.pool.task1;import com.xie.thread.pool.task1.pojo.MyRunnable;
import java.util.concurrent.*;
/*** 处理Runnable任务* */
public class ThreadPoolTest {public static void main(String[] args) {/*** 创建线程池,其各参数具体含义:* 参数一:核心线程数量* 参数二:最大线程数量* 参数三:临时线程存活时间* 参数四:参数三的时间单位* 参数五:任务队列,此处用于 缓存 来自通信管道的任务的* 参数六:线程工厂,用于创建核心线程的* 参数七:任务的拒绝策略,此处用到默认策略,直接拒绝的处理方案,当处理不了时,直接抛异常* 注:线程池可以一直存活,除非主动去关闭* */ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());// 创建任务对象Runnable taskObject = new MyRunnable();// 把任务对象 交给 线程池执行。 注:线程池会自动创建一个新线程,自动处理这个任务,自动执行的!pool.execute(taskObject);pool.execute(taskObject);pool.execute(taskObject);pool.execute(taskObject);pool.execute(taskObject);pool.execute(taskObject);pool.execute(taskObject);// 创建临时线程时机pool.execute(taskObject);pool.execute(taskObject); /** 对于此线程池来说,此第九个任务为极限值 */// 拒绝策略生效时机( 任务数量 > (5 + 4) )// pool.execute(taskObject);/** 等着 线程池的任务 全部执行完毕后,再关闭线程池 */pool.shutdown();// 立即关闭线程池! 不管任务是否执行完毕!// pool.shutdownNow();}
}

处理Callable任务

Callable任务类

package com.xie.thread.pool.task2.pojo;import java.util.concurrent.Callable;
/*** 让这个类实现callable接口  Callable任务类* */
public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}/** 重写call方法 此为线程池后期调用的 任务方法(call方法) */@Overridepublic String call() throws Exception {// 描述线程要执行的任务,返回线程执行完后的返回结果int sum = 0;for (int i = 0; i <= n; i++) {sum += i;}return Thread.currentThread().getName() + " 求出了 1-" + n + " 的和是:" + sum;}
}

测试

package com.xie.thread.pool.task2;import com.xie.thread.pool.task2.pojo.MyCallable;
import java.util.concurrent.*;
/*** 处理Callable任务* Callable任务的最大特点:线程池处理任务完后,可以直接获取处理完任务后的结果* */
public class ThreadPoolTest {public static void main(String[] args) throws Exception {/*** 创建线程池,其各参数具体含义:* 参数一:核心线程数量* 参数二:最大线程数量* 参数三:临时线程存活时间* 参数四:参数三的时间单位* 参数五:任务队列,此处用于 缓存 来自通信管道的任务的* 参数六:线程工厂,用于创建核心线程的* 参数七:任务的拒绝策略,此处用到默认策略,直接拒绝的处理方案,当处理不了时,直接抛异常* 注:线程池可以一直存活,除非主动去关闭* */ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());/** 使用已定义的有参构造器,创建任务对象 Callable对象 并交给线程池 处理*  并返回一个未来任务对象*  */Future<String> futureTask1 = pool.submit(new MyCallable(100));Future<String> futureTask2 = pool.submit(new MyCallable(200));Future<String> futureTask3 = pool.submit(new MyCallable(300));Future<String> futureTask4 = pool.submit(new MyCallable(400));Future<String> futureTask5 = pool.submit(new MyCallable(500));// 获取执行结果 并打印输出System.out.println(futureTask1.get());System.out.println(futureTask2.get());System.out.println(futureTask3.get());System.out.println(futureTask4.get());System.out.println(futureTask5.get());/** 等着 线程池的任务 全部执行完毕后,再关闭线程池 */pool.shutdown();/** 测试 */// Callable my = new MyCallable(100);// System.out.println(my.call());}
}

使用工具类(Executors)创建线程池

常用API

  
在这里插入图片描述
  

应用案例

测试

package com.xie.thread.pool.tool;import com.xie.thread.pool.task2.pojo.MyCallable;
import java.util.concurrent.*;
/*** --->通过工具类Executors创建线程池对象* Executors是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象** final关键字(修饰符)作用:* 不能被继承,不能被修改???** 注:此工具类中这些静态方法的底层,都是通过 线程池的实现类ThreadPoolExecutor 创建 的线程池对象。* 使用风险:* 大型并发系统环境中使用Executors如果不注意可能会出现系统风险* 所以,建议推荐使用 ThreadPoolExecutor()类 来创建线程池。** 拓展知识:* 核心线程数量配置的参考策略:* 1,计算密集型的任务:核心线程数量 = CPU的核数 + 1* 2,IO密集型的任务:核心线程数量 = CPU核数 * 2* */
public class ThreadPoolTest {public static void main(String[] args) throws Exception {/** 通过工具类Executors方式 创建 线程池对象 新建固定线程数量的线程池(此处定义为3个) */final ExecutorService pool = Executors.newFixedThreadPool(3);/** 使用已定义的有参构造器,创建任务对象 Callable对象 并交给线程池 处理*  并返回一个未来任务对象*  */Future<String> futureTask1 = pool.submit(new MyCallable(100));Future<String> futureTask2 = pool.submit(new MyCallable(200));Future<String> futureTask3 = pool.submit(new MyCallable(300));Future<String> futureTask4 = pool.submit(new MyCallable(400));Future<String> futureTask5 = pool.submit(new MyCallable(500));// 获取执行结果 并打印输出System.out.println(futureTask1.get());System.out.println(futureTask2.get());System.out.println(futureTask3.get());System.out.println(futureTask4.get());System.out.println(futureTask5.get());/** 等着 线程池的任务 全部执行完毕后,再关闭线程池 */pool.shutdown();}
}

:此工具类中的这些静态方法的底层都是通过 线程池的 实现类ThreadPoolExecutor 来创建 线程池对象的。


拓展

思考

  
在这里插入图片描述
  

任务拒绝策略

  
在这里插入图片描述
  

参考视频

黑马磊哥


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

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

相关文章

极大似然估计概念的理解——统计学习方法

目录 1.最大似然估计的概念的理解1 2.最大似然估计的概念的理解2 3.最大似然估计的概念的理解3 4.例子 1.最大似然估计的概念的理解1 最大似然估计是一种概率论在统计学上的概念&#xff0c;是参数估计的一种方法。给定观测数据来评估模型参数。也就是模型已知&#xff0c;参…

芯驰D9评测(2)--系统环境配置连接

linux开发板的软件开发三件套&#xff1a; 建立连接-->建立交叉编译环境-->建立驱动开发环境。 如果我们不涉及镜像的深度定制&#xff0c;只是平台化应用的话 1. 建立串口连接 查看手册&#xff0c; 获取接口定义说明&#xff1a; 板载一共两个端子&#xff0c;三个…

2023年山东省安全员C证证考试题库及山东省安全员C证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年山东省安全员C证证考试题库及山东省安全员C证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

Flutter笔记:手写并发布一个人机滑动验证码插件

Flutter笔记 手写一个人机滑块验证码 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/133529459 写 Flut…

备忘录:Docker基础操作与常用命令

文章目录 Docker基础操作1.1 Docker在线安装1.1.1 安装基础软件包1.1.2 安装docker主程序1.1.2.1 设置国内源1.1.2.2 安装docker 1.2 Docker离线安装1.2.1 下载离线安装包1.2.2 安装docker依赖包以及docker 1.3 设置自启动并启动dokcer1.4 安装docker-compose1.4.1 命令行下载文…

解决nvm切换node版本失败的终极办法-秒杀网上99%的水文

nvm是一款强大的node多版本管理器&#xff0c;可以轻易选择你需要的node版本&#xff0c;这对win7平台简直就是超好的福音&#xff1a;可以突破node 14.15以上的安装限制。 但是nvm安装有一个巨大的坑点&#xff1a;nvm use 版本号以后&#xff0c;并没有生效&#xff0c;nvm …

uni-app:js修改元素样式(宽度、外边距)

效果 代码 1、在<view>元素上添加一个ref属性&#xff0c;用于在JavaScript代码中获取对该元素的引用&#xff1a;<view ref"myView" id"mybox"></view> 2、获取元素引用 &#xff1a;const viewElement this.$refs.myView.$el; 3、修改…

认识柔性数组

在C99中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做柔性数组成员 限制条件是&#xff1a; 结构体中最后一个成员未知大小的数组 1.柔性数组的形式 那么我们怎样写一个柔性数组呢 typedef struct st_type {int i;int a[0];//柔性数组成员 }ty…

HTTP协议,请求响应

、概述 二、HTTP请求协议 三、HTTP响应协议 四、请求数据 1.简单实体参数 RequestMapping("/simpleParam")public String simpleParam(RequestParam(name "name" ,required false ) String username, Integer age){System.out.println (username "…

免杀对抗-DLL劫持免杀

C&Py-DLL劫持-语言-调用加载 1.使用visual studio创建项目 2.将文件名重命名为.c后缀 3.将如下加载器代码生成dll文件 加载器代码&#xff1a; #include "pch.h" #include <Windows.h> #include <stdio.h> #include <string.h>#pragma comment…

【C语言】汉诺塔 —— 详解

一、介绍 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;又称河内塔&#xff0c;是一个源于印度古老传说的益智玩具。大焚天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大焚天命令婆罗门把圆盘从下面开始按…

Pikachu靶场——不安全的文件下载(Unsafe Filedownload)

文章目录 1. Unsafe Filedownload1.1 Unsafe Filedownload1.1.1 源代码分析1.1.2 漏洞防御 1.2 不安全的文件下载防御措施 1. Unsafe Filedownload 不安全的文件下载概述&#xff1a; 文件下载功能在很多web系统上都会出现&#xff0c;一般我们当点击下载链接&#xff0c;便会…

【正点原子】无法打开 源 文件 “linux/time_types.h“ (dependency of “linux/ide.h“)

问题描述 在VS code中些驱动代码时显示&#xff1a; 检测到 #include 错误。请更新 includePath。已为此翻译单元(/home/alientek/linux/atk-mp1/Linux_Drivers/2_LED/led.c)禁用波形曲线。C/C(1696) 无法打开 源 文件 "linux/time_types.h" (dependency of "…

性格敏感怎么办?改变性格敏感的方法有哪些?

有这么一群人&#xff0c;他们的情绪很容易受到外界的影响&#xff0c;就像一汪宁静的湖水&#xff0c;被风轻易地吹出皱纹。他们有着高度敏感的神经&#xff0c;外界稍微一点风吹草动&#xff0c;就会牵动他们紧张的情绪。 他们的思维就像脱缰的野马&#xff0c;生活中任何一…

第15届蓝桥STEMA测评真题剖析-2023年8月20日Scratch编程中级组

[导读]&#xff1a;超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成&#xff0c;后续会不定期解读蓝桥杯真题&#xff0c;这是Scratch蓝桥杯真题解析第155讲。 第15届蓝桥第1次STEMA测评&#xff0c;这是2023年8月20日举办的STEMA&#xff0c;比赛仍然采取线上形式。这…

UWB高精度定位系统:引领精准定位技术的新纪元

在现代社会中&#xff0c;精准定位技术对于各行各业都至关重要。为了满足对高精度定位的需求&#xff0c;超宽带&#xff08;Ultra-Wideband, UWB&#xff09;技术应运而生。UWB高精度定位系统以其出色的定位精度和多样化的应用领域而备受关注。本文将深入探讨UWB高精度定位系统…

MAC手动修复『已损坏』问题 终端运行命令报错处理

安装一些第三方软件会出现已损坏的报错提醒&#xff0c;需要用命令sudo xattr -rd com.apple.quarantine进行修复&#xff0c;但是终端提示命令错误&#xff0c;怎么版 错误有几种&#xff1a; No module named ‘pkg_resources’ 这是mac电脑上python2&#xff0c;python3并…

分布式操作系统

分布式操作系统属于多机操作系统&#xff0c;能够统一一套计算机集群&#xff0c;相比单机系统&#xff0c;分布式操作系统在管理计算机集群方面要简单很多。各种分布式的基础功能&#xff0c;都集中到分布式操作系统来实现&#xff0c;而不是单机系统的应用软件来实现&#xf…

2023最新简易ChatGPT3.5小程序全开源源码+全新UI首发+实测可用可二开(带部署教程)

源码简介&#xff1a; 2023最新简易ChatGPT3.5小程序全开源源码全新UI首发&#xff0c;实测可以用&#xff0c;而且可以二次开发。这个是最新ChatGPT智能AI机器人微信小程序源码&#xff0c;同时也带部署教程。 这个全新版本的小界面设计相当漂亮&#xff0c;简单大方&#x…

springboot 简单配置mongodb多数据源

准备工作&#xff1a; 本地mongodb一个创建两个数据库 student 和 student-two 所需jar包&#xff1a; # springboot基于的版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>&l…