Executors:为什么阿里不待见我?

2024-01-14 14:20
文章标签 阿里 待见 executors

本文主要是介绍Executors:为什么阿里不待见我?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是Excutors,一个老实的工具类。

有个叫老三的程序员在文章 要是以前有人这么讲线程池,我早就该明白了!里挖了一个坑,说要把我介绍给大家认识认识。

我其实挺委屈的,作为一个没得感情,老实干活的工具类,我却上了阿里巴巴的黑名单。他们在一本叫《Java开发手册》的册子里写道:

禁止使用Excutors

作者画外音:人家为啥给你拉黑,不写的清清楚楚嘛,你有啥可委屈的。而且你这个家伙就是表面看起来老实,活是你干的吗?干活的不都是小老弟ThreadPoolExecutor。来,我一个个给你数。

1. newFixedThreadPool

FixedThreadPool,是一个固定大小的线程池。

看一下它的源代码实现:

    public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}

直接调用ThreadPoolExecutor的构造方法。

  • 核心线程数最大线程数相同
  • 使用LinkedBlockingQueue作为任务队列

FixedThreadPoolexecute()运行示意图:

FixedThreadPool

整体运行过程:

  • 当前运行线程少于corePoolSize,则创建新线程执行任务
  • 当前运行线程大于corePoolSize,将任务加入LinkedBlockingQueue
  • 线程池中线程执行完任务后,会循环从LinkedBlockingQueue中获取任务执行

因为使用无界队列LinkedBlockingQueue来存储不能执行的任务,所以不会触发拒绝服务策略,可能会导致OOM

2. newSingleThreadExecutor

SingleThreadExecutor是使用单个线程工作的线程池。

实现源码如下:

    public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}

直接调用ThreadPoolExecutor的构造方法。

  • 核心线程数最大线程数都是1
  • 使用LinkedBlockingQueue作为任务队列

SingleThreadExecutor的运行流程:

SingleThreadExecutor运行流程

  • 当前无运行线程,创建一个线程来执行任务
  • 当前有线程运行,将任务加入LinkedBlockingQueue
  • 线程执行完任务后,会循环从LinkedBlockingQueue中获取任务来执行

这里用了无界队列LinkedBlockingQueue,同样可能会导致OOM

3. newCachedThreadPool

CachedThreadPool是一个会根据需要创建新线程的线程池。

实现源码:

    public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}

直接调用ThreadPoolExecutor的构造方法。

  • 核心线程数为0,最大线程数是非常大的一个数字Integer.MAX_VALUE
  • 使用没有容量的SynchronousQueue作为工作队列
  • keepAliveTime设置为60L,空闲线程空闲60秒之后就会被终止

CachedThreadPool的运行流程:

CachedThreadPool执行流程

  • 如果当前有空闲线程,使用空闲线程来执行任务
  • 如果没有空闲线程,创建一个新线程来执行任务
  • 新建的线程执行完任务后,会执行poll(keepAliveTime,TimeUnit.NANOSECONDS),在SynchronousQueue里等待60s

这里线程池的大小没有限制,可能会无限创建线程,导致OOM

4. newScheduledThreadPool

ScheduledThreadPool是一个具备调度功能的线程池。

实现源码:

    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);}

可以看到,这个线程池不太一样,它调用的是ScheduledThreadPoolExecutor的构造方法。

    public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());}
  • 最大线程数是Integer.MAX_VALUE,无限大
  • 使用DelayedWorkQueue作为任务队列

ScheduledThreadPoolExecutor执行任务的流程:

ScheduledThreadPool执行流程

主要分为两大部分:

  1. 调用scheduleAtFixedRate()/scheduleWithFixedDelay()方法,会向DelayQueue添加一个ScheduledFutureTask
  2. 线程池的线程从DelayQueue中获取ScheduledFutureTask,然后执行任务。

它同样可以无限创建线程,所以也存在OOM的风险。

为了实现周期性执行任务,ScheduledThreadPoolExecutorThreadPoolExecutor进行了一些改造[4]:

  • ScheduledFutureTask来作为调度任务的实现

    它主要包含了3个成员变量time(任务将要被执行的具体时间)sequenceNumber(任务的序号)period(任务执行的间隔周期)

  • 使用DelayQueue作为任务队列

    DelayQueue封装了了一个PriorityQueue,会对对队列中的ScheduledFutureTask进行排序,排序的优先级time>sequenceNumber。

ScheduledThreadPoolExecutor执行流程

ScheduledThreadPoolExecutor的任务执行主要分为4步:

  1. 线程池里的线程1DelayQueue中获取已到期的ScheduledFutureTask(DelayQueue.take())
  2. 线程1执行这个ScheduledFutureTask
  3. 线程1修改ScheduledFutureTasktime变量为下次将要被执行的时间。
  4. 线程1把这个修改time之后的ScheduledFutureTask放回DelayQueue中(DelayQueue.add())

Excutors自述:这,这……工具类出的问题不叫bug。虽然我偷懒不干活,还可能会OOM,但我还是一个好工具类,呜呜……

作者:是啊,其实Excutors有什么错呢?它只是一个没得感情的工具类,有错的只是不恰当地用它的人。所以,知其然且知其所以然,搞懂原理,灵活应用。我们应该像一个士兵一样,不只是会扣动扳机,还会拆解保养枪械。

我是三分恶,一个号称能文能武的全栈开发。

点赞关注不迷路,咱们下期见!



参考:

[1]. 《Java并发编程的艺术》

[2]. 讲真 这次绝对让你轻松学习线程池

[3]. 小傅哥 《Java面经手册》

[4]. 《Java并发编程之美》

[5]. 阿里巴巴《Java开发手册》


更多精彩原创,技术交流👇👇👇

这篇关于Executors:为什么阿里不待见我?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/605470

相关文章

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

阿里云服务器ces

允许公网通过 HTTP、HTTPS 等服务访问实例 https://help.aliyun.com/document_detail/25475.html?spm=5176.2020520101.0.0.3ca96b0b3KGTPq#allowHttp

LLM系列 | 38:解读阿里开源语音多模态模型Qwen2-Audio

引言 模型概述 模型架构 训练方法 性能评估 实战演示 总结 引言 金山挂月窥禅径,沙鸟听经恋法门。 小伙伴们好,我是微信公众号《小窗幽记机器学习》的小编:卖铁观音的小男孩,今天这篇小作文主要是介绍阿里巴巴的语音多模态大模型Qwen2-Audio。近日,阿里巴巴Qwen团队发布了最新的大规模音频-语言模型Qwen2-Audio及其技术报告。该模型在音频理解和多模态交互

超越IP-Adapter!阿里提出UniPortrait,可通过文本定制生成高保真的单人或多人图像。

阿里提出UniPortrait,能根据用户提供的文本描述,快速生成既忠实于原图又能灵活调整的个性化人像,用户甚至可以通过简单的句子来描述多个不同的人物,而不需要一一指定每个人的位置。这种设计大大简化了用户的操作,提升了个性化生成的效率和效果。 UniPortrait以统一的方式定制单 ID 和多 ID 图像,提供高保真身份保存、广泛的面部可编辑性、自由格式的文本描述,并且无需预先确定的布局。

node.js实现阿里云短信发送

效果图 实现 一、准备工作 1、官网直达网址: 阿里云 - 短信服务 2、按照首页提示依次完成相应资质认证和短信模板审核; 3、获取你的accessKeySecret和accessKeyId; 方法如下: 获取AccessKey-阿里云帮助中心 4、获取SignName(签名名称)和 TemplateCode(模板code); 二、代码实现 1、项目结构 【/c

JS_阿里云oss视频上传后,如何获取视频封面

当您需要获取视频封面、提取视频关键帧图像进行视频编辑,或者提取视频中特定场景帧图像用于视频监控等时,可以将视频上传至OSS存储空间,然后通过本文所示方法进行视频截帧。 使用示例 本文示例使用的Bucket为杭州地域名为oss-console-img-demo-cn-hangzhou的Bucket,视频外网访问地址为: https://oss-console-img-demo-cn-hangzho

阿里编码规约怎么使用?

阿里编码规约是一个插件,可以检测到代码中不规范的代码。 使用步骤: 1.去下载安装插件: 2.安装插件后,重启android studio。会发现: 3.使用此插件。 打开一个java文件,点击红色框的按钮。 4.检测结果。如下图

SpringBoot整合Minio及阿里云OSS(配置文件无缝切换)

SpringBoot整合Minio及阿里云OSS 文章目录 SpringBoot整合Minio及阿里云OSS1.Minio安装测试1.Docker安装启动容器 2.创建bucket3.上传文件修改权限 2.SpringBoot整合Minio及阿里云OSS1.公共部分抽取2.Minio配置整合1.添加pom依赖2.添加配置文件3.操作接口实现 3.阿里云OSS配置整合1.pom依赖2.添加

[SaaS] 阿里妈妈-万相营造

阿里妈妈 创意中心 - 首页基于阿里妈妈营销平台,提供从图文到视频再到落地页的素材级智能化创意支持,是您营销创意数字资产累积和升值的阵地,最大化提升营销的效率和效果。https://chuangyi.taobao.com/ 1.AI图片 商品图:

【对线面试官】阿里面试经历,有些人走一步看一步就挂了

点击上方蓝色字体,选择“设为星标” 回复”资源“获取更多资源 这个其实说来就话长了。是小编曾经面试阿里妈妈的经历。 这次面试最终在HR面挂掉,以至于后面回忆起来,仍然是一桩美谈。 这次面试长达一个月之久,共经历了4轮技术面,1轮HR。前四轮面试过关斩将,简直开了挂一般,跟面试官正面对线,丝毫不虚。听我一一道来。 第一轮 第一面是电话面试,晚上10点半。我特么一脸问号?你们这是刚加完班吧?事实上我