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

一道并发的面试题,控制并发数量

文章目录

    • 题目要求
    • 解析题目
    • 总结发现
    • 补全SuperTask代码,实现逻辑
    • 完整代码和结果

题目要求

在这里插入图片描述

解析题目

我们先看看这道题目的规律,看到前两个,还是挺正常的,任务1 10s后输出,任务 2 5s后输出。
任务3 却是8s后输出,但明明传入的是3s,可结果是8s后输出,这里其实我们就该考虑到,这个8s那来的,结合前面两个,可以想到,5 + 3 正好8s,所以这个任务3是等任务2执行完后在执行的。
再往下看任务4 这里传入4s,却是12s后输出的,很明显就是 8 + 4 的结果,所以任务4是在任务2和任务3执行的,而任务5 却是15s后输出,那就是在任务1 后执行的。

总结发现

如下所示
在这里插入图片描述

其实可以联想到,这里有两条任务线在并发执行,任务1 由于10s后才输出,任务2 是5s后输出,所以任务3 会排在任务2后面执行,这就是为啥任务3 明明传入3s,但结果是8s后才输出了,依次类推,任务4接上,到任务5时,任务1执行完毕,此时任务2那条线,任务4在执行占用,所以任务5接在任务1后执行。

补全SuperTask代码,实现逻辑

class SuperTask {constructor(parallelNum = 2) {this.parallelNum = parallelNum // 最大并发数this.taskList = [] // 存储任务线this.runNum = 0 // 正在执行的任务数}add(task) {// 不管怎样,先把任务存在数组里面,由于外面是.then,所以这里是promise,为了执行任务的时候,执行结束要回调,所以把resolve,reject也保存起来return new Promise((resolve, reject) => {this.taskList.push({task,resolve,reject,})// 存进来的时候调下执行函数this._run()})}_run() {// 如果正在执行的数量 小于 最大并发数 并且 存储任务线大于0, 那么就执行存储任务中的任务while (this.runNum < this.parallelNum && this.taskList.length) {// 拿出来任务,并删除存储任务线的数据const { task, resolve, reject } = this.taskList.shift()// 因为外面的timeout方法返回的是一个promise,所以这里是异步需要.thentask().then(resolve, reject).finally(() => {// 执行完了,正在执行任务数要--,并且再次调用下执行函数this.runNum--this._run()})// 这里正在执行的任务数要++this.runNum++}}
}

完整代码和结果

class SuperTask {constructor(parallelNum = 2) {this.parallelNum = parallelNum // 最大并发数this.taskList = [] // 存储任务线this.runNum = 0 // 正在执行的任务数}add(task) {// 不管怎样,先把任务存在数组里面,由于外面是.then,所以这里是promise,为了执行任务的时候,执行结束要回调,所以把resolve,reject也保存起来return new Promise((resolve, reject) => {this.taskList.push({task,resolve,reject,})// 存进来的时候调下执行函数this._run()})}_run() {// 如果正在执行的数量 小于 最大并发数 并且 存储任务线大于0, 那么就执行存储任务中的任务while (this.runNum < this.parallelNum && this.taskList.length) {// 拿出来任务,并删除存储任务线的数据const { task, resolve, reject } = this.taskList.shift()// 因为外面的timeout方法返回的是一个promise,所以这里是异步需要.thentask().then(resolve, reject).finally(() => {// 执行完了,正在执行任务数要--,并且再次调用下执行函数this.runNum--this._run()})// 这里正在执行的任务数要++this.runNum++}}
}// 题目要求如下 依次执行addTask函数,输出结果如下 任务1 10s后输出,任务2 5s后输出,任务3 8s后输出,任务4 12s后输出,任务5 15s后输出
const superTask = new SuperTask()function timeout(time) {return new Promise((resolve) => {setTimeout(resolve, time)})
}function addTask(time, name) {superTask.add(() => timeout(time)).then(() => {console.log(`任务${name}完成`)})
}addTask(10000, 1) // 10s后输出
addTask(5000, 2) // 5s后输出
addTask(3000, 3) // 8s后输出
addTask(4000, 4) // 12s后输出
addTask(5000, 5) // 15s后输出// 任务1 (10s后输出) => 任务5 (15s后输出)
// 任务2 (5s后输出) => 任务3 (8s后输出) => 任务4 (12s后输出)

在这里插入图片描述

http://www.xdnf.cn/news/554491.html

相关文章:

  • Spring的AOP在什么场景下会失效?
  • 贝叶斯优化+CNN+LSTM=小论文创新点
  • 物联网(IoT)智能项目全景指南:技术构架、实现细节与应用实践
  • Oracle如何解决LATCH:CACHE BUFFERS CHAINS
  • java接口自动化初识
  • 保证数据库 + redis在读写分离场景中事务的一致性
  • 985,成立人工智能学院
  • Java高频面试之并发编程-19
  • 第50天-使用Python+Qt+DeepSeek开发AI运势测算
  • 基于springboot3 VUE3 火车订票系统前后端分离项目适合新手学习的项目包含 智能客服 换乘算法
  • 当前主流的传输技术(如OTN、IP-RAN、FlexE等)
  • C++STL之string
  • 产业互联网+三融战略:重构企业增长密码
  • 人工智能+:职业技能培训的元命题与能力重构
  • Linux 正则表达式 扩展正则表达式 gawk
  • 101个α因子#8
  • Java DTO 深度解析
  • JUC编程monitor、锁膨胀以及相关关键字
  • 定时从接口下载数据到本地
  • 免费插件集-illustrator插件-Ai插件-路径尖角圆角化
  • 天然产物在食品医药美妆领域的创新应用研究
  • 图像噪声模拟
  • 安装PostgreSQL
  • 解决javafx组件缺失导致运行程序报错的问题
  • Spring Boot中的分布式缓存方案
  • PID项目---硬件设计
  • Javascript 编程基础(2)基础知识 | 2.3、语法规则
  • 操作系统----软考中级软件工程师(自用学习笔记)
  • 循环神经网络
  • 机器人编程基础---C语言中的高级特性