手写JAVA线程池

前言

手写一个简单的java线程池:重点关注,如何确保一直有运行的线程?如何确保线程消费提交的任务信息?。一直保存有运行的线程底层使用的是死循环。使用消息队列确保信息的提交和消费。消息队列使用先进先出原则。

步骤

线程池核心点 :复用机制

  • 1、提前创建好固定的线程一直在运行状态----死循环实现
  • 2、提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行
  • 3、正在运行的线程就从队列中获取该任务执行

1、创建固定线程

根据传入的参数,确定要生成几个一直运行的线程。比如传入的参数是2,就会创建出2个一直运行的线程。一直运行的线程使用死循环来实现。

public class MyTestExecutors {private List<WorkThread> workThread;/*** 最大线程数* @param maxThreadCount*/public MyTestExecutors(int maxThreadCount){//提前创建好固定的线程一直在运行状态---死循环实现workThread = new ArrayList<WorkThread>(maxThreadCount);for (int i = 0; i < maxThreadCount; i++) {new WorkThread().start();}}class WorkThread extends Thread{@Overridepublic void run() {while (true){}}}
}

2、提交任务到消息队列

提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行。

提示:offer()方法是Java队列中经常使用的方法,它的作用是向队列尾部添加一个元素。具体来说,offer()方法会将指定的元素插入到此队列的末尾,如果队列已满,它将返回false。否则,它会返回true,表示已成功添加了元素。

    /*** 线程任务缓存到一个并发队列集合* @param command* @return*/public boolean execute(Runnable command){return runnableDeque.offer(command);}

public class MyTestExecutors {private List<WorkThread> workThread; //工作线程private BlockingDeque<Runnable> runnableDeque; //队列/*** @param maxThreadCount 最大线程数* @param dequeSize      缓存消息队列*/public MyTestExecutors(int maxThreadCount,int dequeSize){//1、限制队列容量缓存runnableDeque = new LinkedBlockingDeque<Runnable>(dequeSize);//2、提前创建好固定的线程一直在运行状态---死循环实现workThread = new ArrayList<WorkThread>(maxThreadCount);for (int i = 0; i < maxThreadCount; i++) {new WorkThread().start();}}class WorkThread extends Thread{@Overridepublic void run() {while (true){}}}/*** 线程任务缓存到一个并发队列集合* @param command* @return*/public boolean execute(Runnable command){return runnableDeque.offer(command);}public static void main(String[] args) {MyTestExecutors testExecutors = new MyTestExecutors(2, 2);for (int i = 0; i < 10; i++) {final int finalI = i;testExecutors.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+","+finalI);}});}}
}

3、线程消费消息队列

正在运行的线程就从队列中获取该任务执行

    class WorkThread extends Thread{@Overridepublic void run() {while (true){Runnable runnable = runnableDeque.poll();if(runnable != null){runnable.run();}}}}

4、测试

2个的情况,两个固定线程还未执行任务,且队列中只缓存了两个线程任务。

在这里插入图片描述

4个的情况,固定两个线程正在执行任务,队列中缓存了两个线程任务。
在这里插入图片描述

5、线程停止【完整代码】

如何在线程任务执行完成后,停止两个一直存在的线程。需要将死循环的条件改变,通过给一个标志位。在任务结束后,将该标志位设置为false,同时需要判断,队列中的任务是否执行结束。队列中缓存的任务全部结束,才停止线程。

while (isRun || runnableDeque.size()>0)

package com.grg.demo.testDemo02;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;/*** @author zyz* @version 1.0* @data 2023/7/11 23:01* @Description: 手写线程池*  线程池核心点 :复用机制 -----*  1、提前创建好固定的线程一直在运行状态----死循环实现*  2、提交的线程任务缓存到一个并发队列集合中,交给我们正在运行的线程执行*  3、正在运行的线程就从队列中获取该任务执行*/
public class MyTestExecutors {private List<WorkThread> workThread; //工作线程private BlockingDeque<Runnable> runnableDeque; //队列private Boolean isRun = true;/**** @param maxThreadCount 最大线程数* @param dequeSize      缓存消息队列*/public MyTestExecutors(int maxThreadCount,int dequeSize){//2、限制队列容量缓存runnableDeque = new LinkedBlockingDeque<Runnable>(dequeSize);//1、提前创建好固定的线程一直在运行状态---死循环实现workThread = new ArrayList<WorkThread>(maxThreadCount);for (int i = 0; i < maxThreadCount; i++) {new WorkThread().start();}}class WorkThread extends Thread{@Overridepublic void run() {while (isRun || runnableDeque.size()>0){Runnable runnable = runnableDeque.poll();if(runnable != null){runnable.run();}}}}/*** 线程任务缓存到一个并发队列集合* @param command* @return*/public boolean execute(Runnable command){return runnableDeque.offer(command);}public static void main(String[] args) {MyTestExecutors testExecutors = new MyTestExecutors(2, 2);for (int i = 0; i < 10; i++) {final int finalI = i+1;testExecutors.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+","+finalI);}});}testExecutors.isRun = false;}
}

在这里插入图片描述

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

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

相关文章

iOS开发 - 系统自带框架实现扫一扫功能

iOS 扫一扫 利用系统自带框架实现扫一扫功能 一 项目配置 扫一扫功能相机和相册权限&#xff0c;在info.plist中设置询问用户是否允许访问的权限。 info.plist加入NSCameraUsageDescription、NSPhotoLibraryUsageDescription、NSPhotoLibraryAddUsageDescription <key&g…

spring 详解二 IOC(Bean xml配置及DI)

配置列表 Xml配置 功能描述 <bean id"" class""></bean> Bean的id&#xff0c;配置id会转为Bean名称和不配就是全限定类名 <bean name"" ></bean> Bean的别名配置&#xff0c;存储在Factory的aliasMap中通过别名也…

操作系统Linux—day01

编程 网页 软件 网站项目 知识点&#xff1a; 前端页面&#xff1a;HTML css JavaScript JQuery VUE 数据库&#xff1a;Oracle MySQL 服务器&#xff1a;服务器的操作系统Linux Http://115.159.96.174:8090/EasyBuy/ www.baidu.com>http://180.101.49.12/ 后台技术…

几何伙伴行泊一体解决方案入选浦东人工智能十大创新技术

2023年7月8日&#xff0c;在全球瞩目的世界人工智能大会&#xff08;WAIC&#xff09;浦江东岸分会场&#xff0c;主题为“引领未来&#xff0c;赋能焕新”的“2023世界人工智能大会浦东论坛”隆重举办。浦东新区作为全国首个人工智能创新应用先导区&#xff0c;正打造上海人工…

electron的(maximize)最大化方法会导致头部白色横条以及四周大黑边

参考文章&#xff1a;https://www.w3cways.com/2505.html 感谢这位博主 我在使用win.maximize()后发现应用程序虽然最大化了&#xff0c;但是四周和顶部有一定宽度的黑边白边&#xff0c;在百度一段时间后没有发现其他人有这个问题 &#x1f614;唉 必现步骤&#xff1a; 只要…

前端理解的HTTP缓存(作用、缓存策略、缓存控制机制、应用)

一、HTTP缓存有什么作用&#xff1f; 缓存是为了重复使用而被存储的&#xff0c;可以减少浏览器和服务器之间通信的次数、降低网络延迟、加速页面加载、提高用户体验性等。不但能使网页打开速度更快&#xff0c;还能减少服务器的压力。 二、 浏览器的缓存策略有哪些&#xff1…

【MySQL】不就是事务

前言 嗨咯&#xff0c;小伙伴们大家好呀&#xff0c;我已经一个星期没有更新了&#xff0c;实在抱歉&#xff01;本期我们要学习MySQL初阶中的最后一课&#xff0c;MySQL数据库中的事务也算是近几年面试必考的问题&#xff0c;所以我们一定要认真学习。 目录 前言 目录 一、事…

派盘支持单向和双向资料同步

派盘作为一款本地云存储解决方案&#xff0c;不仅支持双向同步&#xff0c;还提供了设置部分文件夹单向同步的功能。这意味着用户可以根据自己的需求&#xff0c;精确控制文件夹的同步方向&#xff0c;以实现更有针对性的文件管理和同步。 π-Disk派盘 – 知识管理专家 派盘的…

最详细的下载安装PicGo图床配合Typora使用

1.node.js下载安装1.2 检验安装成功 2. PicGo下载安装3. 配置Gitee【配合PicGo使用】3.1 获取PicGo的token 4. 配置PicGo4.1 下载插件4.2 配置图床[Gitee]4.3 配置Typora 5. 上传图片到Gitee【重要】6.解决配置错误 1.node.js下载安装 【node.js下载链接】点击跳转页面&#x…

JVM (simple Version)

简介 JVM 其实就是一个Java进程 , 从操作系统申请一大块内存区域, 供 java 代码使用 . 申请出的内存 , 进一步划分 , 给出不同的用途 . JVM 内存区域划分 : 堆中存放就是 new 出来的对象. (成员变量) 栈 是用来维护方法之间的调用关系 (局部变量) 元数据区(或者叫方法区) 存放的…

day34-servlet 分页

0目录 servlet 1.分页 分页逻辑1&#xff1a;数据库中20条记录&#xff0c;要求每页5条数据&#xff0c;则一共有4页 分页逻辑2&#xff1a;数据库中21条记录&#xff0c;要求每页5条数据&#xff0c;则一共有5页 分页逻辑3&#xff1a;数据库中19条记录&#xff0c;要求每页…

Java阶段五Day04

Java阶段五Day04 文章目录 Java阶段五Day04订单交易案例调整项目案例环境克隆项目验证maven环境数据库导入本地mysql核心业务 实现csmall-for-jsd-all纵向拆分csmall-for-jsd-order系统 删除module&#xff08;删除maven项目&#xff09;idea记录maven忽略pull远程解决冲突git对…