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

【JavaEE】【多线程】线程池

目录

  • 一、线程池
  • 二、ThreadPoolExecutor类讲解
    • 2.1 构造方法
      • 2.1.1 corePoolSize和maximumPoolSize
      • 2.1.2 KeepAliveTime和unit
      • 2.1.3 workeQueue
      • 2.1.4 threadFactory
      • 2.1.5 handler
  • 三、简易构造线程池
  • 四、自己实现一个简单线程池

一、线程池

线程池:线程池可以简单理解为存放多个线程的一段空间。

线程池的作用:就是把线程提前创建好,放入线程池中,需要线程时从线程池中取,线程用完归还到线程池中。这样就可以减少线程创建的开销。

一个操作系统包含内核和以及其它计算机系统所必须的组件,
而内核中包含了操作系统的各种核心功能:管理硬件设备,给软件提供稳定的运行环境。
而在计算机中认为有一段代码在应用程序中完成,执行过程是可控的,而在内核中完成的过程是不可控的。而可控的操作比不可控更加高效。

直接创建线程比从线程池拿线程开销小的原因:

  • 直接创建线程,需要内核配合完成,是不可控的;
  • 先创建好在从线程池中去取,取线程就是可控的操作。

Java标准库中提供的类ThreadPoolExecutor就是创建线程池的类。

二、ThreadPoolExecutor类讲解

2.1 构造方法

在ThreadPoolExecutor类中主要提供了下面四种不同参数的构造方法。
我们讲解第四种7种参数版本中每个参数代表什么。

2.1.1 corePoolSize和maximumPoolSize

int corePoolSize代表核心线程数的个数。核心线程随着线程池的创建而创建,销毁而销毁。
int maximumPoolSize代表最大线程数。就是核心线程数与非核心线程数之和。非核心线程是自适应创建的,不繁忙的时候就销毁,繁忙的时候在创建。

2.1.2 KeepAliveTime和unit

long KeepAliveTime代表非核心线程允许空闲的最大时间。
TimeUnit unit代表时间单位。
TimeUnit是一个枚举类。

2.1.3 workeQueue

blockingQueue<Runnable> workQueue代表工作队列,也是一个阻塞队列。线程池本身就是一个生产者消费者模型,调用submit方法就是在生产,线程池中的线程就是消费者。

2.1.4 threadFactory

ThreadFactory threadFactory给线程Thread类提供的工厂类。
ThreadFactory是一个接口。

并不能直接出来一个对象,需要我们自己创建类实现该接口。
也可以使用Java中自带的默认的方式Executors类下的defaultThreadFactory方法:Executors.defaultThreadFactory();

工厂模式:工厂模式就是主要用来弥补构造方法的缺陷的一种设计模式。当构造方法因为重载限制时,可以当前类中使用static静态方法(这个静态方法也称为工厂方法)或者单独使用一个类提供静态方法(这个类称为工厂类),在静态方法中调用构造方法。

例子:我们表示一个点的坐标有使用(x,y)坐标系的方法和(ρ,θ)来表示。
像下面这样提供构造方法就会报错。

但是我们像下面这样提供一个工厂类就可以避免了。

class Point {double x;double y;double ρ;double θ;
}
class PointFactory {public static void PointXY(double x, double y) {Point point = new Point();point.x = x;point.y = y;}public static void Pointρθ(double ρ, double θ) {Point point = new Point();point.ρ = ρ;point.θ = θ;}}

2.1.5 handler

RejectedExectionHandler handler表示 拒绝策略。

在调用submit,将任务给到任务队列,而在线程池中不会像阻塞队列一样,队列满了就阻塞,而是提供了4中拒绝策略。

  • AbortPolicy:线程池中直接抛出异常,撂挑子不干了。
  • CallerRunsPolicy:让调用submit方法的线程自己执行这个任务。
  • DiscardOldestPolicy:丢弃线程池中最老的任务,给新任务腾出空间。
  • DiscardPolicy:丢弃线程池中最新的任务,即submit的任务。

三、简易构造线程池

在Java中提供了Exectors类对ThreadPoolExecutor类进行了进一步封装,可以使用这个类来创建一个默认的线程池。

四、自己实现一个简单线程池

我们创建一个固定容量的线程池,只实现其中的submit方法和构造方法。

  • 构造一个阻塞队列;
  • 在构造方法中传要创建的线程数,循环创建线程,在线程中循环拿出队列中的任务,并执行run方法,不要忘记start线程。
  • 在submit方法中只要将任务put到队列中即可。
public class MyThreadPoolExecutor {//BlockingDeque<Runnable> queue = new LinkedBlockingDeque<>(1000);public MyThreadPoolExecutor(int n ) {//创建n个线程for (int i = 0; i < n; i++) {Thread thread = new Thread(() -> {try{while(true) {Runnable task = queue.take();task.run();}} catch (InterruptedException e) {e.printStackTrace();}});thread.start();}}public void submit(Runnable task) throws InterruptedException {queue.put(task);}
}

http://www.mrgr.cn/news/60303.html

相关文章:

  • Qt5.15.x源码编译
  • Linux学习笔记 | sudo命令的基本使用
  • PostgreSQL-06-入门篇-集合运算
  • opencv-platform实现人脸识别
  • C++的相关习题(2)
  • 动态规划算法专题(九):完全背包问题
  • WebGIS开发之编辑功能(分割、融合、捕捉、追踪)
  • 2023年中国县域统计年鉴(县市卷+乡镇卷)(excel格式)
  • 声学气膜馆:品牌发布会的理想之选—轻空间
  • Labview通讯测试耗时
  • 支持向量机SVM简述
  • Spring Boot摄影工作室:构建Web版在线服务平台
  • jieba:智能文本处理的利器,结巴中文分词
  • 培育增长新动能,英搏尔数字化管理升级与创新的实践
  • Go语言编译详解
  • PHP员工管理系统小程序
  • 充电宝哪个牌子好?2024精选五款优质充电宝,入门避坑必看攻略!
  • 了解 SQL 查询执行顺序
  • 突破AI极限!GPT写的英语作文在全国大学生大赛中得分99!
  • 【论文阅读】jina-embeddings-v3: Multilingual Embeddings With Task LoRA
  • 代码随想录(十二)——图论
  • VLAN聚合的实验配置
  • 前端内存空间(堆、栈、队列、拷贝、垃圾回收)
  • 【React】React 18:新特性与重大更新解析
  • Redis安装说明
  • Colorful/七彩虹将星X17 Pro 22 Win11原厂OEM系统 带COLORFUL一键还原