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,一经查实,立即删除!

相关文章

人工智能基础_机器学习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

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;为了提高运算量处理更多…

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

充电暖手宝因为它的便携性&#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;指对某种事物发展…

计算机网络期末复习-Part3

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

Python爬虫——入门爬取网页数据

目录 前言 一、Python爬虫入门 二、使用代理IP 三、反爬虫技术 1. 间隔时间 2. 随机UA 3. 使用Cookies 四、总结 前言 本文介绍Python爬虫入门教程&#xff0c;主要讲解如何使用Python爬取网页数据&#xff0c;包括基本的网页数据抓取、使用代理IP和反爬虫技术。 一、…

RedisDesktopManager连接不上redis的解决方法

RedisDesktopManager连接不上redis的解决方法 RedisDesktopManager是一款连接redis数据库的客户端。 当连接不上redis的时候&#xff0c;解决方案&#xff1a; 第一步&#xff1a;在自己的本机外面试下&#xff0c;能不能连接上虚拟机 打开cmd,使用ping 虚拟机ip地址。如果…

ElasticSearch7.x - HTTP 操作 - 索引操作

创建索引 对比关系型数据库,创建索引就等同于创建数据库 在 Postman 中,向 ES 服务器发 PUT 请求 :http://192.168.254.101:9200/shopping 说明 {"acknowledged"【响应结果】: true, # true 操作成功"shards_acknowledged"【分片结果】: true, # 分片操…

Apache RocketMQ - 概述

2022年&#xff0c;RocketMQ 5.0的正式版发布&#xff0c;相比于4.0版本而言&#xff0c;架构走向云原生化&#xff0c;并且覆盖了更多的业务场景。 如何从互联网时代演进到云时代&#xff1f; 1. 消息队列演进史 操作系统、数据库、中间件是基础软件的三驾马车&#xff0c;…

《QT从基础到进阶·二十》QThreadPool线程池的使用

什么情况下比较适合用线程池&#xff1f; 比如我有上百个任务要同时处理&#xff0c;难道开上百个线程&#xff1f;NO&#xff01;&#xff01;&#xff01; 有了线程池的加持&#xff0c;自动给任务分配线程处理&#xff0c; 多线程不再是真爱~ 线程池创建&#xff1a; 1、自…