Coding面试题之手写线程池

原理图 

JDK线程池原理

 实现代码

1.线程类(PoolThread

这个类用于执行任务队列中的任务。

public class PoolThread extends Thread {private final Queue<Runnable> taskQueue;private boolean isStopped = false;private long lastTaskTime = System.currentTimeMillis();public PoolThread(Queue<Runnable> queue) {taskQueue = queue;}public void run() {while (!isStopped()) {try {Runnable task;synchronized (taskQueue) {// 等待任务while (taskQueue.isEmpty() && !isStopped()) {taskQueue.wait();}if (isStopped()) break;task = taskQueue.poll();}task.run();lastTaskTime = System.currentTimeMillis(); // 更新上次任务完成的时间} catch (Exception e) {// 异常处理}}}public synchronized void stopThread() {isStopped = true;this.interrupt(); // 中断线程}public synchronized boolean isStopped() {return isStopped;}public boolean isIdleFor(long keepAliveTime) {return (System.currentTimeMillis() - lastTaskTime) > keepAliveTime;}
}

这里的“空闲时间”通常是指自线程上次执行任务以来经过的时间,而不是线程的创建时间。目的是为了确定线程是否在一段时间内没有被用于执行任何任务。 

2.线程池类(ExtendedThreadPool

这个类用于管理线程和任务的分配。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;public class ExtendedThreadPool {private final Queue<Runnable> taskQueue;private final List<PoolThread> threads;private boolean isStopped;private int maxNumThreadSize;private int minNumThreadSize;private int keepAliveTime;private Timer maintainTimer;public ExtendedThreadPool(int minNumThreadSize, int maxNumThreadSize, int keepAliveTime) {this.minNumThreadSize = minNumThreadSize;this.maxNumThreadSize = maxNumThreadSize;this.keepAliveTime = keepAliveTime;this.taskQueue = new LinkedList<>();this.threads = new ArrayList<>();this.isStopped = false;this.maintainTimer = new Timer();for (int i = 0; i < this.minNumThreadSize; i++) {threads.add(new PoolThread(taskQueue));}for (PoolThread thread : threads) {thread.start();}maintainThreadPool();}public synchronized void execute(Runnable task) {if (this.isStopped) throw new IllegalStateException("ThreadPool is stopped");this.taskQueue.add(task);this.taskQueue.notify();if (threads.size() < maxNumThreadSize) {PoolThread newThread = new PoolThread(taskQueue);threads.add(newThread);newThread.start();}}private void maintainThreadPool() {maintainTimer.schedule(new TimerTask() {@Overridepublic void run() {synchronized (taskQueue) {// 如果任务多于线程,且线程数小于最大线程数,则增加线程if (!taskQueue.isEmpty()  && taskQueue.size()> threads.size()  &&  threads.size() < maxNumThreadSize) {PoolThread newThread = new PoolThread(taskQueue);threads.add(newThread);newThread.start();}// 检查线程是否超过空闲时间,如果是,则移除线程Iterator<PoolThread> iterator = threads.iterator();while (iterator.hasNext()) {PoolThread thread = iterator.next();if (thread.isIdleFor(keepAliveTime)) {iterator.remove();thread.stopThread();}}}}}, 0, keepAliveTime * 1000);
}public synchronized void stop() {this.isStopped = true;for (PoolThread thread : threads) {thread.stopThread();}maintainTimer.cancel();}
}

上面的代码如何保证线程复用?

  1. 任务到达时唤醒: 当一个新任务被添加到队列中并且队列之前是空的,execute 方法会调用 taskQueue.notify(),这会唤醒一个正在等待的线程。被唤醒的线程随后会从队列中取出任务(Runnable)并执行。

  2. 线程不立即终止: 线程在执行完一个任务后不会立即终止。相反,它会再次检查队列是否有新的任务。如果有,线程会继续执行新的任务。一个线程在其生命周期内可以执行多个任务,而不是每完成一个任务就销毁并创建一个新的线程。

相关文章

【精选】线程池的核心参数和运行机制_线程池的核心参数以及工作机制-CSDN博客

线程池内运行的线程抛异常,线程池会怎么办_线程池线程异常后会结束线程吗-CSDN博客

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

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

相关文章

传奇世界如何添加新的装备

大家应该都知道传世所有的装备列表都是保存在StdItems.DB 物品数据库中&#xff0c;各种装备的属性等信息也是在这个数据库中来定义的&#xff0c;比如某个武器的攻击力&#xff0c;佩戴要求&#xff0c;外观都是在这个数据库中定义。 然后我们要修改或添加新的装备&#xff0…

老版本goland无法调试新版本go问题处理

背景 无法调试1.20版本b 报错如下&#xff1a; No goroutine selected 懒人不想升级goland版本。 处理方法 1.安装最新的dlv工具 go install github.com/go-delve/delve/cmd/dlvlatest 2.找到刚刚安装的dlv工具&#xff0c;并复制 # 位于$GOPATH的bin目录下&#xff0c;如…

人工智能基础_机器学习022_使用正则化_曼哈顿距离_欧氏距离_提高模型鲁棒性_过拟合_欠拟合_正则化提高模型泛化能力---人工智能工作笔记0062

然后我们再来看一下,过拟合和欠拟合,现在,实际上欠拟合,出现的情况已经不多了,欠拟合是 在训练集和测试集的准确率不高,学习不到位的情况. 然后现在一般碰到的是过拟合,可以看到第二个就是,完全就把红点蓝点分开了,这种情况是不好的, 因为分开是对训练数据进行分开的,如果来…

C语言 预处理详解

目录 1.预定义符号 2.#define 2.1#define 定义标识符 2.2#define 定义宏 2.3#define 替换规则 2.4#和## 2.4.1# 的作用 2.4.2## 的作用 2.5 带有副作用的宏参数 2.6宏和函数的对比 对比 **2.7内联函数 2.8命名约定 3.#undef **4.命令行定义 5.条件编译 常…

npm install 报错 chromedriver 安装失败的解决办法

npm install chromedriver --chromedriver_cdnurlhttp://cdn.npm.taobao.org/dist/chromedriver

ubuntu 内网源如何搭建 —— 筑梦之路

为什么要搭建内网源&#xff1f; 原因&#xff1a;内网开发环境由于其特定原因不能上外网&#xff0c;所以需要本地环境下的内网源来方便开发人员下载安装软件 搭建建议 单独使用一块磁盘来存放源文件或者单独一个目录下&#xff0c;避免混淆。 环境说明 ubuntu 系统 两张…

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:

错误描述如下所示&#xff1a; 我们将错误拉到最下面如下所示为导致异常的原因&#xff1a; Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type com.example.reviewmybatisplus.Service.UserService available: expec…

双编码器构建机器人零力拖动/导纳控制思路

前言 这篇博客主要记录昨日与实验室大佬针对UR5机器人拖动示教功能实现的思路。由于本人并非主攻力控方面。直到昨天在做实验的时候&#xff0c;与力控组的大佬讨论过后才了解UR机器人实现导纳控制的思路。 关于导纳控制/零力拖动 导纳控制与阻抗控制单从字面去理解很容易记…

PHP编写采集药品官方数据的程序

在 PHP 中编写爬虫程序&#xff0c;首先我们需要引入一些必要的库&#xff0c;如 curl 和 file_get_contents。然后&#xff0c;我们需要设置爬虫ip信息&#xff0c;以便我们可以从指定的爬虫ip服务器上获取数据。 // 引入必要的库 require_once curl.php;// 设置爬虫ip信息 $p…

CMake教程--QT项目使用CMake

CMake教程--QT项目使用CMake Chapter1 CMake教程--QT项目使用CMake1. Basic Cmake Based Project2. Executable VS Library3. Every module has its own CMakeList.txt in its folder3.1 不推荐的做法&#xff1a;3.2 推荐的做法 4. 强制以Debug, Release, RelWithDebInfo, Min…

[游戏中的图形学实时渲染技术] Part1 实时阴影技术

原理篇&#xff1a; 常见的渲染方程如下&#xff1a; &#xfffd;&#xfffd;(&#xfffd;,&#xfffd;&#xfffd;) &#xfffd;&#xfffd;(&#xfffd;,&#xfffd;&#xfffd;) ∫Ω&#xfffd;&#xfffd;(&#xfffd;,&#xfffd;&#xfffd;)&#xf…

Hls学习(一)

1&#xff1a;CPU、DSP、GPU都算软件可编程的硬件 2&#xff1a;dsp在递归方面有所减弱&#xff0c;在递归方面有所增强&#xff0c;比如递归啊等&#xff0c;GPU可以同时处理多个进程&#xff0c;对于大块数据&#xff0c;流处理比较适用 3&#xff1a;为了提高运算量处理更多…

HTTPS安全相关-通信安全的四个特性-ssl/tls

230-TLS是什么 1.http不安全 由于 HTTP 天生“明文”的特点&#xff0c;整个传输过程完全透明&#xff0c;任何人都能够在链路中截获、修改或者伪造请求 / 响应报文&#xff0c;数据不具有可信性 &#xff1b; “代理服务”。它作为 HTTP 通信的中间人&#xff0c;在数据上下…

暖手宝+充电宝设计方案 可实现快速升温和充电 低成本充电电流可选

充电暖手宝因为它的便携性&#xff0c;既能供暖又能当充电宝使用而备受人们喜爱。是冬天暖手供暖的必备神器。 目前&#xff0c;市场常见的暖手宝大致有三个类型&#xff0c;分别是加热水的热水袋、通过化学反应放热的铁粉袋子和锂电供电的智能暖手宝。与常见的暖手宝不同&…

巨好用又实用的18款3dMax插件!

3dMax是一款功能强大的 3D 软件&#xff0c;具有建模、动画、粒子动力学等许多强大功能。但并不是每个人都能有效地利用max的每一个功能&#xff0c;例如&#xff0c;很多人发现3dmax粒子流太难使用&#xff0c;3ds max蒙皮工具也是如此。 这让我们一些专业的开发公司或个人和…

Python学习笔记--自定义类型的枚举

三、自定义类型的枚举 但有些时候我们需要控制枚举的类型&#xff0c;那么我们可以 Enum 派生出自定义类来满足这种需要。通过修改上面的例子&#xff1a; #!/usr/bin/env python3 # -*- coding: UTF-8 -*- from enum import Enum, uniqueEnum(Month, (Jan, Feb, Mar, Apr, M…

配置cuda和cudnn出现 libcudnn.so.8 is not a symbolic link问题

cuda版本为11.2 问题如图所示&#xff1a; 解决办法&#xff1a; sudo ln -sf /usr/local/cuda-11.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8.1.1 /usr/local/cuda-11.2/targets/x86_64-linux/lib/libcudnn_adv_train.so.8 sudo ln -sf /usr/local/cuda-11.2/targ…

时间序列预测(1) — 时间序列预测研究综述

目录 1 什么是时间序列预测? 2 时间序列预测的应用场景与分类 3 时间序列数据的特性 4 时序预测评价指标 5 基于深度学习的时间序列预测方法 5.1 卷积神经网络 5.2 循环神经网络 5.3 Transformer类模型 1 什么是时间序列预测? 时间序列&#xff1a;指对某种事物发展…

Mybatis教程

Mybatis教程 参考&#xff1a; MyBatis教程看这一篇就够啦&#xff0c;简单又全面&#xff08;IDEA版&#xff09; MyBatis详解 MyBatis(一文学会&#xff01;) MyBatis教程&#xff08;看这一篇就够了&#xff09; mybatis查询结果对象值为null的情况 mybatis查询结果对…

计算机网络期末复习-Part3

1、rdt1.0&#xff0c;rdt2.0&#xff0c;rdt3.0的底层信道模型 RDT 1.0: 完全可靠的底层信道&#xff0c;没有比特差错&#xff0c;也没有分组丢失。 RDT 2.0: 具有比特差错的底层信道&#xff0c;有比特差错&#xff0c;但没有分组丢失。 RDT 3.0: 具有差错和丢包的底层信道…