Java实现简易线程池

一.线程池的概念

创建Java线程需要给线程分配堆栈内存以及初始化内存,还需要进行系统调用,频繁地创建和销毁线程会大大降低系统的运行效率,采用线程池来管理线程有以下好处:

  1. 提升性能:线程池能独立负责线程的创建、维护和分配
  2. 线程管理:每个Java线程池会保持一些基本的线程统计信息,对线程进行有效管理 

二.代码部分

1.处理任务类:向线程池中提交任务

定义两个链表:分别向其中添加任务线程

package ThreadPool;import java.util.ArrayList;
//处理任务的线程
public class WorkThread implements Runnable{public ArrayList<Runnable> runnableArrayList;public WorkThread(ArrayList<Runnable> runnableArrayList){this.runnableArrayList=runnableArrayList;}@Overridepublic void run() {Runnable work=null;while (true){synchronized (runnableArrayList){//上锁while(runnableArrayList.isEmpty()){//当list为空 即没有任务时 线程等待try {System.out.println(Thread.currentThread().getName()+"线程等待...");runnableArrayList.wait();} catch (Exception e) {throw new RuntimeException(e);}}//list不为空,取出第一个任务work=runnableArrayList.remove(0);}work.run();//任务运行 注意用run()}}
}

2.线程池类

package ThreadPool;import java.util.ArrayList;public class ThreadPool{public ArrayList<WorkThread> workThreadArrayList;//任务listpublic ArrayList<Runnable> runnableArrayList;//线程listpublic int workSize;//任务数量public ThreadPool(int core,int size){workThreadArrayList=new ArrayList<>(core);//核心线程数corerunnableArrayList=new ArrayList<>(size);//任务数量sizeworkSize=size;for(int i=0;i<core;i++){WorkThread wt=new WorkThread(runnableArrayList);//新建一个任务new Thread(wt).start();//任务运行workThreadArrayList.add(wt);//将任务加入任务list}}//添加任务的方法public void add(Runnable runnable){//参数是Runnablesynchronized (runnableArrayList){if(runnableArrayList.size()<workSize){runnableArrayList.add(runnable);runnableArrayList.notify();}else{System.out.println("队列已满...");}}}
}

3.处理任务的对象

package ThreadPool;public class ThreadDemo {public static void main(String[] args) {
//main中定义一个线程池参数为核心线程数和线程池尺寸ThreadPool threadPool=new ThreadPool(5,20);for(int i=0;i<25;i++){threadPool.add(new Work(i));//调用添加方法}}
}
//待处理任务对象
class Work implements Runnable{int count=0;//任务编号public Work(int count){this.count=count;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"正在处理任务"+count);try {Thread.sleep(3000);} catch (Exception e) {throw new RuntimeException(e);}}
}

 三.线程池的任务调度流程
如果当前工作线程数量小于核心线程数量,执行器总是优先创建一个任务线程,而不是从线程队列中获取一个空闲线程
如果线程池中总的任务数量大于核心线程池数量,新接收的任务将被加入阻塞队列中,一直到阻塞队列已
当完成一个任务的执行时,执行器总是优先从阻塞队列中获取下一个任务,并开始执行,一直到阻塞队列为
在核心线程池数量已经用完、阻塞队列也已经满了的场景下,如果线程池接收到新的任务,将会为新任务创建一个线程(非核心线程),并且立即开始执行新任务
在核心线程都用完、阻塞队列已满的情况下,一直会创建新线程去执行新任务,直到池内的线程总数超出maximumPoolSize。如果线程池的线程总数超过maximumPoolSize,线程池就会拒绝接收任务,当新任务过来时,会为新任务执行拒绝策略
注意点

核心和最大线程数量、BlockingQueue队列等参数如果配置得不合理,可能会造成异步任务得不到预期的并发执行,造成严重的排队等待现象
线程池的调度器创建线程的一条重要的规则是:在corePoolSize已满之后,还需要等阻塞队列已满,才会去创建新的线程
example: 设置核心线程数量为1,阻塞队列为100,有5个任务待执行(假设极端情况下任务一直执行不接受),则只有1个任务可以被执行,其他4个任务在阻塞队列中,而不是创建新线程进行处理(阻塞队列未满)

四.任务阻塞队列
特点:在一个线程从一个空的阻塞队列中获取元素时线程会被阻塞,直到阻塞队列中有了元素;当队列中有元素后,被阻塞的线程会自动被唤醒

常见的几种阻塞队列的实现:

ArrayBlockingQueue:是一个数组实现的有界阻塞队列(有界队列),队列中的元素按FIFO排序,ArrayBlockingQueue在创建时必须设置大小
LinkedBlockingQueue:是一个基于链表实现的阻塞队列,按FIFO排序任务,可以设置容量(有界队列),不设置容量则默认使用Integer.Max_VALUE作为容量(无界队列)
PriorityBlockingQueue:是具有优先级的无界队列

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

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

相关文章

css - - - - - 去除图片默认的白色背景(混合模式 mix-blend-mode)

去除图片默认的白色背景&#xff08;mix-blend-mode&#xff09; 1. 需求描述2. 原图展示3. 原代码展示4. 使用混合模式(mix-blend-mode)5.修改后效果 1. 需求描述 图片含有白色地图&#xff0c;想要将其去掉 2. 原图展示 3. 原代码展示 <div><img src*****/> &…

现场可重构CPLD芯片应用案例—蓝牙音箱

我司英尚微提供的高性能数模混合现场可重构IC、通用可配置的模数混合芯片内部集成丰富的模拟资源和数字资源&#xff0c;可轻松替代电路中的各种标准器件&#xff0c;并按照客户要求组合成最优小型ASIC&#xff0c;缩短开发周期&#xff0c;降低成本。下面介绍LS98002现场可重构…

【Windows】操作系统之任务管理器(第一篇)

一、操作系统简介 Windows操作系统是由微软公司&#xff08;Microsoft&#xff09;开发的一款图形操作系统&#xff0c;它以其强大的功能和广泛的用户基础&#xff0c;成为了目前世界上用户使用最多、兼容性最强的操作系统之一。以下是关于Windows操作系统的详细介绍&#xff…

vue3前端开发-小兔鲜项目-人气推荐栏目的前端渲染

vue3前端开发-小兔鲜项目-人气推荐栏目的前端渲染&#xff01;今天和大家分享一下&#xff0c;人气推荐栏目的前端页面如何渲染内容。 经历过上一次的&#xff0c;新鲜好物的栏目渲染之后&#xff0c;我们已经熟练了&#xff0c;vue3的接口调用&#xff0c;数据渲染到页面中的整…

golang开发环境搭建与踩坑记录

文章目录 一、安装下载1、go环境2、ide 二、基本使用1、运行2、结构体与方法函数指针3、闭包4、指针5、map6、接口7、异常 三、包管理1、go mod语法2、项目下载所有依赖 一、安装下载 1、go环境 下载地址&#xff1a;https://go.dev/dl/ 或者&#xff1a;https://golang.goog…

python的with语句

1.with语句的作用 在 Python 中&#xff0c;with 语句用于创建一个上下文管理器&#xff0c;以更简洁和安全的方式管理资源。 其主要优点是可以确保在代码块执行完毕后&#xff0c;相关资源能够被正确释放或清理&#xff0c;即使在代码块内部发生了异常。 以下是一个使用 with…

【动态规划】力扣2266.统计打字方案数

Alice 在给 Bob 用手机打字。数字到字母的 对应 如下图所示。在这里插入图片描述 为了 打出 一个字母&#xff0c;Alice 需要 按 对应字母 i 次&#xff0c;i 是该字母在这个按键上所处的位置。 比方说&#xff0c;为了按出字母 ‘s’ &#xff0c;Alice 需要按 ‘7’ 四次。…

LLM推理需要占用多少显存

搬运&#xff1a; AI开发者de频道&#xff1a;专题文章显示

c++一句话求前缀和,不用循环

partial_sum 是 C 标准库中的一个函数&#xff0c;用于计算给定范围内元素的部分和。它接受三个参数&#xff1a; 起始迭代器&#xff08;包含在计算范围内的第一个元素&#xff09;结束迭代器&#xff08;不包含在计算范围内的最后一个元素&#xff09;输出迭代器&#xff08…

DP-适配器模式代码重新理解

package com.designpatterns.adapter;/*** 定义鸭子接口*/ public interface Duck {/*** 定义鸭子呱呱叫(quack)*/public void quack();public void fly(); }package com.designpatterns.adapter;/*** 实现一个绿头鸭*/ public class MallarDuck implements Duck{Overridepubl…

Linux中运用xsync实现免密集群分发

一、前言 今天搭建了三台虚拟机的集群&#xff0c;在集群中部分操作在三台虚拟机上的操作都一致&#xff0c;为了提高效率&#xff0c;就需要配置xsync实现集群分发。 二、设置免密登录 1.生成公钥和私钥 ssh-keygen -t rsa一直敲回车&#xff0c;会生成两个文件&#xff0c…

C#中处理Socket粘包

在C#中使用Socket进行网络通信时&#xff0c;粘包问题是常见的。粘包问题通常发生在TCP协议中&#xff0c;因为TCP是流式协议&#xff0c;数据可能会被分割成多个包发送&#xff0c;也可能多个小包会被合并成一个大包接收。 处理粘包问题的常见方法是使用消息分隔符或消息长度…

【Qt+opencv】ROI与图像混合

文章目录 前言ROIROI是什么如何提取ROI 图像混合整体混合线性混合 局部混合 总结 前言 在计算机视觉和图像处理中&#xff0c;我们经常需要对图像的某一部分&#xff08;也就是ROI&#xff0c;Region of Interest&#xff09;进行操作。这些操作可能包括滤波、缩放、旋转等。同…

SpringBoot 跨域请求处理全攻略:从原理到实践

文章目录 SpringBoot 如何处理跨域请求&#xff1f;你能说出几种方法&#xff1f;跨域请求概述跨域解决方案1. 使用CrossOrigin注解2. 使用WebMvcConfigurer配置类3. 使用过滤器&#xff08;Filter&#xff09;4. 使用Spring Security处理CORS5.使用Spring Cloud Gateway处理CO…

灵雀云AML:赋能金融AI,构建数智时代核心竞争力

在人工智能&#xff08;AI&#xff09;技术的迅猛发展中&#xff0c;金融行业正迈入变革的新时代。AI不仅在优化投资决策、信用评估、实时监控和欺诈识别方面展现出强大功能&#xff0c;还极大地提升了客户体验、降低了运营成本&#xff0c;并推动了产品创新。面对智能时代的挑…

C#知识|账号管理系统:多条件动态查询条件的编写。

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 在项目开发中涉及到许多通过多个条件勾选来实现动态的多个条件查询的情况&#xff0c; 此节记录多条件查询的后台代码编写&#xff0c;以下为学习笔记。 01 实现原理 通过界面输入框输入或者下拉框下拉选择任意查询…

《RuoYi基于SpringBoot+Vue前后端分离的Java快速开发框架学习》系列博客_Part2_添加菜单

系列文章目录 Part1:启动RouYi 文章目录 系列文章目录Part1:启动RouYi 实现添加菜单功能来显示新的音图分析页面&#xff08;所截图片都是在已经添加菜单完成后的情况下&#xff09;一、建立一个菜单二、建立数据库1、通过数据库软件建立一个表&#xff0c;供我们使用&#xf…

强化学习算法DQN实现

DQN的基本思想 Q学习&#xff1a;Q学习是一种基于值函数的强化学习方法&#xff0c;目的是通过学习状态-动作值函数Q(s, a)来指导智能体的动作选择。Q函数表示在状态s采取动作a后能够获得的期望总回报。 深度神经网络&#xff1a;使用深度神经网络来近似Q函数。输入是状态s&am…

【Ngix】快速上手,由浅入深

内容概述 1、nginx 简介 &#xff08;1&#xff09;介绍 nginx 的应用场景和具体可以做什么事情 &#xff08;2&#xff09;介绍什么是反向代理 &#xff08;3&#xff09;介绍什么是负载均衡 &#xff08;4&#xff09;介绍什么是动静分离 2、nginx 安装 &#xff08;1…

Leetcode - 周赛406

目录 一&#xff0c;3216. 交换后字典序最小的字符串 二&#xff0c;3217. 从链表中移除在数组中存在的节点 三&#xff0c;3218. 切蛋糕的最小总开销 I 四&#xff0c;3219. 切蛋糕的最小总开销 II 一&#xff0c;3216. 交换后字典序最小的字符串 本题要求交换一次相邻字符…