创建线程池

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

目录

  • 如何创建线程池及处理相应任务
    • 线程池定义
    • 解决的问题(需求)
    • 工作原理
    • 实现线程池创建示意图
    • 重要构造器
    • 创建线程池(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.hqwc.cn/news/124288.html

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

相关文章

SG Former论文学习笔记

超越SWin和CSWin Transformer的新模型 代码地址&#xff1a;https://github.com/OliverRensu/SG-Former 论文地址&#xff1a;https://arxiv.org/pdf/2308.12216.pdf ViT在各种视觉任务中虽然成功&#xff0c;但它的计算成本随着Token序列长度的增加呈二次增长&#xff0c;这在…

OpenGLES:绘制一个混色旋转的3D球体

一.概述 前面几篇博文讲解了如何使用OpenGLES实现不同的3D图形 本篇博文讲解怎样实现3D世界的代表图形&#xff1a;一个混色旋转的3D球体 二.球体解析 2.1 极限正多面体 如果有学习过我前几篇3D图形绘制的博文&#xff0c;就知道要想绘制一个3D图形&#xff0c;首先要做的…

MYSQL的CRUD语句(含c++代码)

一.MySQl表的创建与删除 创建语句与删除语句 注意&#xff1a; 主键的数据类型&#xff0c;不可以是变长度类型需要()限制长度&#xff0c;表名字需要使用符号来包围。 二.MySQl数据插入 三.MySQl数据删除 四.MySQl数据更新 使用语句 SET SQL_SAFE_UPDATES 0; show variabl…

MySQL优化、锁、总结常见问题

慢 SQL 如何定位呢&#xff1f; 慢 SQL 的监控主要通过两个途径&#xff1a; 慢查询日志&#xff1a;开启 MySQL 的慢查询日志&#xff0c;再通过一些工具比如 mysqldumpslow 去分析对应的慢查询日志&#xff0c;当然现在一般的云厂商都提供了可视化的平台。服务监控&#xf…

Python数据透视表

Python数据透视表 1、Excel数据透视表2、Python数据透视表 1、Excel数据透视表 数据透视表&#xff08;Pivot Table&#xff09;是一种交互式的表&#xff0c;可以进行某些计算&#xff0c;如求和与计数等。所进行的计算与数据跟数据透视表中的排列有关 之所以称为数据透视表…

知识图谱-Neo4j使用详解

neo4j应用场景 知识图谱欺诈检测实时推荐引擎反洗钱主数据管理供应链管理增强网络和IT运营管理能力数据谱系身份和访问管理材料清单 图数据库neo4j简介 关系查询&#xff1a;mysql和neo4j性能对比 neo4j的特性和优点&#xff1a; Neo4j-CQL简介 neo4j的Cypher语言是为处理图…

智能合约漏洞,Dyna 事件分析

智能合约漏洞&#xff0c;Dyna 事件分析 1. 漏洞简介 https://twitter.com/BlockSecTeam/status/1628319536117153794 https://twitter.com/BeosinAlert/status/1628301635834486784 2. 相关地址或交易 攻击交易 1&#xff1a; https://bscscan.com/tx/0x7fa89d869fd1b89e…

Hadoop启动后jps发现没有DateNode解决办法

多次使用 Hadoop namenode -format 格式化节点后DateNode丢失 找到hadoop配置文件core-site.xml查找tmp路径 进入该路径&#xff0c;使用rm -rf data删除data文件 再次使用Hadoop namenode -format 格式化后jps后出现DateNode节点

【Java 进阶篇】MySQL启动与关闭、目录结构以及 SQL 相关概念

MySQL 服务启动与关闭 MySQL是一个常用的关系型数据库管理系统&#xff0c;通过启动和关闭MySQL服务&#xff0c;可以控制数据库的运行状态。本节将介绍如何在Windows和Linux系统上启动和关闭MySQL服务。 在Windows上启动和关闭MySQL服务 启动MySQL服务 在Windows上&#x…

java使用数据库连接池

我的jar包名字 这些包都可以去搜索,有很多小伙伴会用网盘给我们.导入jar包就是复制然后粘贴就好了

论文笔记(整理):轨迹相似度顶会论文中使用的数据集

0 汇总 数据类型数据名称数据处理出租车数据波尔图 原始数据&#xff1a;2013年7月到2014年6月&#xff0c;170万条数据 ICDE 2023 Contrastive Trajectory Similarity Learning with Dual-Feature Attention 过滤位于城市&#xff08;或国家&#xff09;区域之外的轨迹 过…

Transformer学习-self-attention

这里写自定义目录标题 Self-attentionMulti-head self-attention用self-attention解决其他问题 Self-attention 用Wq、Wk、Wv分别乘输入向量得到q、k、v向量 用每个q向量乘所有的k向量得到对应项的attention&#xff0c;即用每项的query向量去匹配所有的key向量&#xff0c;得…