来源:blog.csdn.net/dabusiGin/

article/details/105327873

Executor是不建议的

Executors类为我们提供了各种类型的线程池,经常使用的工厂方法有:

public static ExecutorService newSingleThreadExecutor()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newCachedThreadPool()
public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

书写一段很简单的测试代码:

public class ThreadDemo {public static void main(String[] args) {ExecutorService es = Executors.newSingleThreadExecutor();}
}

当我们用阿里巴巴的P3C检查代码时,会被教育的!!!!

阿里爸爸是不允许这么创建线程池的,上面的警告写的很明确“线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。”(PS:很难得在编译器中看到中文提示,对于英语不好的同学来说,简直是福音,喜极而泣!!!!)

强制使用ThreadPoolExecutor

我们使用ThreadPoolExecutor创建线程池:

public class ThreadDemo {public static void main(String[] args) {ExecutorService es = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(10), Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());}
}

此时,再用P3C检查代码,终于没有报错了。

在华丽的分隔符之后,我们还是有必要从JDK源码的层面深挖一下其中的原理。

首先是静态方法newSingleThreadExecutor()newFixedThreadPool(int nThreads)newCachedThreadPool()。我们来看一下其源码实现(基于JDK8)。

public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
}public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
}

通过查看源码我们知道上述三种静态方法的内部实现均使用了ThreadPoolExecutor类。难怪阿里爸爸会建议通过ThreadPoolExecutor的方式实现,原来Executors类的静态方法也是用的它,只不过帮我们配了一些参数而已。

第二是ThreadPoolExecutor类的构造方法。既然现在要直接使用ThreadPoolExecutor类了,那么其中的初始化参数就要我们自己配了,了解其构造方法势在必行。

ThreadPoolExecutor类一共有四个构造方法,我们只需要了解之中的一个就可以了,因为其他三种构造方法只是帮我们配置了一些默认参数,最后还是调用了它。

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

其中的参数含义是:

  • corePoolSize:线程池中的线程数量;

  • maximumPoolSize:线程池中的最大线程数量;

  • keepAliveTime:当线程池线程数量超过corePoolSize时,多余的空闲线程会在多长时间内被销毁;

  • unit:keepAliveTime的时间单位;

  • workQueue:任务队列,被提交但是尚未被执行的任务;

  • threadFactory:线程工厂,用于创建线程,一般情况下使用默认的,即Executors类的静态方法defaultThreadFactory();handler:拒绝策略。当任务太多来不及处理时,如何拒绝任务。

对于这些参数要有以下了解:

corePoolSize与maximumPoolSize的关系

首先corePoolSize肯定是 <= maximumPoolSize。

其他关系如下:

  • 若当前线程池中线程数 < corePoolSize,则每来一个任务就创建一个线程去执行;

  • 若当前线程池中线程数 >= corePoolSize,会尝试将任务添加到任务队列。如果添加成功,则任务会等待空闲线程将其取出并执行;

  • 若队列已满,且当前线程池中线程数 < maximumPoolSize,创建新的线程;

  • 若当前线程池中线程数 >= maximumPoolSize,则会采用拒绝策略(JDK提供了四种,下面会介绍到)。

注意:关系3是针对的有界队列,无界队列永远都不会满,所以只有前2种关系。

学习资料:Java进阶视频资源

workQueue

参数workQueue是指提交但未执行的任务队列。若当前线程池中线程数>=corePoolSize时,就会尝试将任务添加到任务队列中。主要有以下几种:

  • SynchronousQueue:直接提交队列。SynchronousQueue没有容量,所以实际上提交的任务不会被添加到任务队列,总是将新任务提交给线程执行,如果没有空闲的线程,则尝试创建新的线程,如果线程数量已经达到最大值(maximumPoolSize),则执行拒绝策略。

  • LinkedBlockingQueue:无界的任务队列。当有新的任务来到时,若系统的线程数小于corePoolSize,线程池会创建新的线程执行任务;当系统的线程数量等于corePoolSize后,因为是无界的任务队列,总是能成功将任务添加到任务队列中,所以线程数量不再增加。若任务创建的速度远大于任务处理的速度,无界队列会快速增长,直到内存耗尽。

handler

JDK内置了四种拒绝策略:

  • DiscardOldestPolicy策略:丢弃任务队列中最早添加的任务,并尝试提交当前任务;

  • CallerRunsPolicy策略:调用主线程执行被拒绝的任务,这提供了一种简单的反馈控制机制,将降低新任务的提交速度。

  • DiscardPolicy策略:默默丢弃无法处理的任务,不予任何处理。

  • AbortPolicy策略:直接抛出异常,阻止系统正常工作。

至此,我们直接new ThreadPoolExecutor类就不用慌了!!!!

推荐阅读:

世界的真实格局分析,地球人类社会底层运行原理

不是你需要中台,而是一名合格的架构师(附各大厂中台建设PPT)

企业IT技术架构规划方案

论数字化转型——转什么,如何转?

华为干部与人才发展手册(附PPT)

企业10大管理流程图,数字化转型从业者必备!

【中台实践】华为大数据中台架构分享.pdf

华为的数字化转型方法论

华为如何实施数字化转型(附PPT)

超详细280页Docker实战文档!开放下载

华为大数据解决方案(PPT)

阿里巴巴建议的线程池创建方式,你用上了吗?相关推荐

  1. Java创建线程池的方式

    Java创建线程池的方式 文章目录 Java创建线程池的方式 一.通过Executors工厂方法创建 1.Executors.newSingleThreadExecutor() 2.Executors ...

  2. JAVA 三种线程实现创建方式

    JAVA 三种线程实现/创建方式 方式一:继承Thread类 通过继承Thread类来创建一个自定义线程类.Thread类本质上就继承了Runable接口,代表一个线程类.启动线程的唯一办法就是通过T ...

  3. 请使用线程池创建线程,而勿手动创建线程

    在中大型项目中,不可避免地需要执行异步任务,而异步任务的执行则是通过线程而执行的,因此掌握线程是如何创建的则是执行异步任务的第一步. 我们知道,常见的创建线程的方式有: 继承Thread类,重写run ...

  4. 线程池创建与注入,以及线程池参数失效

    一.MyThreadPool public class MyThreadPool {/*** 自定义线程名称,方便的出错的时候溯源*/private static ThreadFactory name ...

  5. 【线程池】线程池创建的参数的作用new ThreadPoolExecutor()

    1.corePoolSize 线程池创建后初始化的就绪线程数量,Thread=new Thread() * 5 2.maximumPoolSize 线程池的最大资源数 3.keepAliveTime ...

  6. java 中线程的创建方式

    如果说在java中创建线程的有几种方式的话,归根结底我认为就两种方式 1.继承Thread类,重写run方法 继承Thread类,如下图重写了run()方法 通过start()方法来启动线程 最后的输 ...

  7. Java和Spring中线程池创建方法

    一.线程池定义 1.JDK中线程池类图 Executor:父接口,所有线程池都实现了这个接口,里面有一个excute()方法用于执行线程 ExecutorService:线程池接口,继承自Execut ...

  8. Java并发编程(01):线程的创建方式,状态周期管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序 ...

  9. java多线程详解及线程池创建

    多线程 线程 线程是独立的执行路径 在程序执行时,即使自己没有创建线程,后台也会有多个线程 main()称为主线程,为系统的入口,用于执行整个程序 在一个进程中如果开辟了多个线程,线程的运行由调度器安 ...

  10. Java线程的创建方式

    文章目录 创建线程的几种方法: ①继承Thread类 ②实现Rullable接口 ③实现Callable接口 Callable接口 Future 接口 FutureTask类 ④使用线程池 Runab ...

最新文章

  1. 用JavaScript和CSS实现“在页面中水平和垂直居中”的时钟
  2. 一图看懂云栖大会「云原生」重磅发布
  3. 字节(byte)简介
  4. 闲来无事,拆个示波器玩玩。
  5. Linux下nginx安装与配置
  6. python浅蓝色对应的代码_浅蓝色Python模块不在m上工作
  7. cassss服务未启动_电梯启动死机故障处理方法
  8. KafkaConsumer源码解析
  9. 图嵌入知识表征の初体验
  10. 快速交付 敏捷开发的特点_敏捷开发的那些事
  11. 大数据之_亿级分布式日志管理ELK_工作笔记001_ELK认识介绍
  12. iOS关于代理的理解
  13. Scratch3.0——作品截图
  14. 卡尔曼滤波算法详细推导
  15. Flips测试类(page43)
  16. 【 java.sql.SQLException: Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_unico】
  17. jQuery调用JSON数据学习第一天
  18. 这个卷走175个国家和地区45亿英镑的“加密女王”忽然失踪,骗局崩盘
  19. SSL证书中的128位加密和256位加密有何区别?
  20. 点赞封面未发送已删除_微信表白新功能:有种喜欢,是给你朋友圈封面点赞

热门文章

  1. 纯C++编写Win32/X64通用Shellcode注入csrss进程
  2. Eclipse小工具 TCP/IP Monitor
  3. 软件架构领域集大成者——《架构之美》读书笔记
  4. 全DIY主题+小工具 正版Win7桌面新体验windows7旗舰版主
  5. 求n的阶乘【VB代码实现】
  6. 牛掰!某厂风控大佬整理的一套黑客学习思维导图及教程!
  7. html立体音乐相册源码,印记工坊立体音乐相册 v 1.8 官方版|印记工坊立体音乐相册官方版|印记工坊立体音乐相册电脑版_最火软件站...
  8. edius多机位多轨编辑
  9. 对西方国家的智能制造研究综述:过去现在和未来
  10. 微星主板怎么开启CPU虚拟化技术VT-X(intel和AMD)