java中创建线程池的方式一般有两种:

Executors工厂方法创建

  1. package com.javaBase.LineDistancePond;
  2.  
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. import java.util.concurrent.ScheduledExecutorService;
  6. import java.util.concurrent.TimeUnit;
  7.  
  8. /**
  9. * 〈一句话功能简述〉;
  10. * 〈功能详细描述〉
  11. *
  12. * @author jxx
  13. * @see [相关类/方法](可选)
  14. * @since [产品/模块版本] (可选)
  15. */
  16. public class TestThreadPoolExecutor {
  17.  
  18. public static void main(String[] args) {
  19. //创建使用单个线程的线程池
  20. ExecutorService es1 = Executors.newSingleThreadExecutor();
  21. for (int i = 0; i < 10; i++) {
  22. es1.submit(new Runnable() {
  23. @Override
  24. public void run() {
  25. System.out.println(Thread.currentThread().getName() + "正在执行任务");
  26. }
  27. });
  28. }
  29. //创建使用固定线程数的线程池
  30. ExecutorService es2 = Executors.newFixedThreadPool(3);
  31. for (int i = 0; i < 10; i++) {
  32. es2.submit(new Runnable() {
  33. @Override
  34. public void run() {
  35. System.out.println(Thread.currentThread().getName() + "正在执行任务");
  36. }
  37. });
  38. }
  39. //创建一个会根据需要创建新线程的线程池
  40. ExecutorService es3 = Executors.newCachedThreadPool();
  41. for (int i = 0; i < 20; i++) {
  42. es3.submit(new Runnable() {
  43. @Override
  44. public void run() {
  45. System.out.println(Thread.currentThread().getName() + "正在执行任务");
  46. }
  47. });
  48. }
  49. //创建拥有固定线程数量的定时线程任务的线程池
  50. ScheduledExecutorService es4 = Executors.newScheduledThreadPool(2);
  51. System.out.println("时间:" + System.currentTimeMillis());
  52. for (int i = 0; i < 5; i++) {
  53. es4.schedule(new Runnable() {
  54. @Override
  55. public void run() {
  56. System.out.println("时间:"+System.currentTimeMillis()+"--"+Thread.currentThread().getName() + "正在执行任务");
  57. }
  58. },3, TimeUnit.SECONDS);
  59. }
  60. //创建只有一个线程的定时线程任务的线程池
  61. ScheduledExecutorService es5 = Executors.newSingleThreadScheduledExecutor();
  62. System.out.println("时间:" + System.currentTimeMillis());
  63. for (int i = 0; i < 5; i++) {
  64. es5.schedule(new Runnable() {
  65. @Override
  66. public void run() {
  67. System.out.println("时间:"+System.currentTimeMillis()+"--"+Thread.currentThread().getName() + "正在执行任务");
  68. }
  69. },3, TimeUnit.SECONDS);
  70. }
  71. }
  72. }

new ThreadPoolExecutor()自定义创建

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

corePoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

unit:参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:

  1. TimeUnit.DAYS; //天
  2. TimeUnit.HOURS; //小时
  3. TimeUnit.MINUTES; //分钟
  4. TimeUnit.SECONDS; //秒
  5. TimeUnit.MILLISECONDS; //毫秒
  6. TimeUnit.MICROSECONDS; //微妙
  7. TimeUnit.NANOSECONDS; //纳秒

workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:

  1. ArrayBlockingQueue
  2. LinkedBlockingQueue
  3. SynchronousQueue
  4. PriorityBlockingQueue
ArrayBlockingQueue和PriorityBlockingQueue使用较少,一般使用LinkedBlockingQueue和SynchronousQueue。线程池的排队策略与BlockingQueue有关。

threadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程做些更有意义的事情,比如设置daemon和优先级等等
handler:表示当拒绝处理任务时的策略,有以下四种取值:

  1. 1AbortPolicy:直接抛出异常。
  2. 2CallerRunsPolicy:只用调用者所在线程来运行任务。
  3. 3DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
  4. 4DiscardPolicy:不处理,丢弃掉。
  5. 5、也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。

ThreadPoolExecutor 源码理解

  1. public static void test(int size) {
  2. ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 20, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));
  3.  
  4. for (int i = 0; i < size; i++) {
  5. poolExecutor.execute(new DemoTask(i));
  6.  
  7. Console.log("poolSize:" + poolExecutor.getPoolSize());
  8. Console.log("corePoolSize:" + poolExecutor.getCorePoolSize());
  9. Console.log("maximumPoolSize:" + poolExecutor.getMaximumPoolSize());
  10. Console.log("queue:" + poolExecutor.getQueue().size());
  11. Console.log("completedTaskCount:" + poolExecutor.getCompletedTaskCount());
  12. Console.log("largestPoolSize:" + poolExecutor.getLargestPoolSize());
  13. Console.log("keepAliveTime:" + poolExecutor.getKeepAliveTime(TimeUnit.SECONDS));
  14.  
  15. }
  16.  
  17. poolExecutor.shutdown();
  18. }
  19.  
  20. class DemoTask implements Runnable {
  21.  
  22. private int taskNum;
  23.  
  24. public DemoTask(int taskNum) {
  25. this.taskNum = taskNum;
  26. }
  27.  
  28. @Override
  29. public void run() {
  30. Console.log(StringUtils.center("正在执行" + taskNum, 20, "="));
  31.  
  32. try {
  33. Thread.sleep(2000);
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. Console.log(StringUtils.center("执行完毕" + taskNum, 20, "="));
  38. }
  39. }

执行结果:

  1. =======正在执行0========
  2. poolSize:1
  3. corePoolSize:5
  4. maximumPoolSize:20
  5. queue:0
  6. completedTaskCount:0
  7. largestPoolSize:1
  8. keepAliveTime:2
  9. poolSize:2
  10. corePoolSize:5
  11. maximumPoolSize:20
  12. queue:0
  13. completedTaskCount:0
  14. =======正在执行1========
  15. largestPoolSize:2
  16. keepAliveTime:2
  17. poolSize:3
  18. corePoolSize:5
  19. maximumPoolSize:20
  20. =======正在执行2========
  21. queue:0
  22. completedTaskCount:0
  23. largestPoolSize:3
  24. keepAliveTime:2
  25. poolSize:4
  26. corePoolSize:5
  27. maximumPoolSize:20
  28. queue:0
  29. =======正在执行3========
  30. completedTaskCount:0
  31. largestPoolSize:4
  32. keepAliveTime:2
  33. poolSize:5
  34. corePoolSize:5
  35. =======正在执行4========
  36. maximumPoolSize:20
  37. queue:0
  38. completedTaskCount:0
  39. largestPoolSize:5
  40. keepAliveTime:2
  41. poolSize:5
  42. corePoolSize:5
  43. maximumPoolSize:20
  44. queue:1
  45. completedTaskCount:0
  46. largestPoolSize:5
  47. keepAliveTime:2
  48. poolSize:5
  49. corePoolSize:5
  50. maximumPoolSize:20
  51. queue:2
  52. completedTaskCount:0
  53. largestPoolSize:5
  54. keepAliveTime:2
  55. poolSize:5
  56. corePoolSize:5
  57. maximumPoolSize:20
  58. queue:3
  59. completedTaskCount:0
  60. largestPoolSize:5
  61. keepAliveTime:2
  62. poolSize:5
  63. corePoolSize:5
  64. maximumPoolSize:20
  65. queue:4
  66. completedTaskCount:0
  67. largestPoolSize:5
  68. keepAliveTime:2
  69. poolSize:5
  70. corePoolSize:5
  71. maximumPoolSize:20
  72. queue:5
  73. completedTaskCount:0
  74. largestPoolSize:5
  75. keepAliveTime:2
  76. poolSize:6
  77. corePoolSize:5
  78. maximumPoolSize:20
  79. queue:5
  80. completedTaskCount:0
  81. largestPoolSize:6
  82. keepAliveTime:2
  83. poolSize:7
  84. corePoolSize:5
  85. maximumPoolSize:20
  86. queue:5
  87. completedTaskCount:0
  88. largestPoolSize:7
  89. keepAliveTime:2
  90. =======正在执行11=======
  91. poolSize:8
  92. corePoolSize:5
  93. maximumPoolSize:20
  94. queue:5
  95. completedTaskCount:0
  96. =======正在执行12=======
  97. =======正在执行10=======
  98. largestPoolSize:8
  99. keepAliveTime:2
  100. poolSize:9
  101. corePoolSize:5
  102. =======正在执行13=======
  103. maximumPoolSize:20
  104. queue:5
  105. completedTaskCount:0
  106. largestPoolSize:9
  107. keepAliveTime:2
  108. poolSize:10
  109. corePoolSize:5
  110. maximumPoolSize:20
  111. =======正在执行14=======
  112. queue:5
  113. completedTaskCount:0
  114. largestPoolSize:10
  115. keepAliveTime:2
  116. poolSize:11
  117. corePoolSize:5
  118. maximumPoolSize:20
  119. queue:5
  120. =======正在执行15=======
  121. completedTaskCount:0
  122. largestPoolSize:11
  123. keepAliveTime:2
  124. poolSize:12
  125. corePoolSize:5
  126. maximumPoolSize:20
  127. queue:5
  128. completedTaskCount:0
  129. =======正在执行16=======
  130. largestPoolSize:12
  131. keepAliveTime:2
  132. poolSize:13
  133. corePoolSize:5
  134. maximumPoolSize:20
  135. =======正在执行17=======
  136. queue:5
  137. completedTaskCount:0
  138. largestPoolSize:13
  139. keepAliveTime:2
  140. poolSize:14
  141. corePoolSize:5
  142. maximumPoolSize:20
  143. queue:5
  144. =======正在执行18=======
  145. completedTaskCount:0
  146. largestPoolSize:14
  147. keepAliveTime:2
  148. poolSize:15
  149. corePoolSize:5
  150. maximumPoolSize:20
  151. =======正在执行19=======
  152. queue:5
  153. completedTaskCount:0
  154. largestPoolSize:15
  155. keepAliveTime:2
  156. =======执行完毕0========
  157. =======正在执行5========
  158. =======执行完毕1========
  159. =======执行完毕2========
  160. =======正在执行6========
  161. =======正在执行7========
  162. =======执行完毕4========
  163. =======正在执行8========
  164. =======执行完毕3========
  165. =======正在执行9========
  166. =======执行完毕13=======
  167. =======执行完毕12=======
  168. =======执行完毕10=======
  169. =======执行完毕11=======
  170. =======执行完毕15=======
  171. =======执行完毕16=======
  172. =======执行完毕14=======
  173. =======执行完毕19=======
  174. =======执行完毕18=======
  175. =======执行完毕17=======
  176. =======执行完毕5========
  177. =======执行完毕7========
  178. =======执行完毕6========
  179. =======执行完毕8========
  180. =======执行完毕9========

参考链接:Java线程池(一)

      Java线程池(二)

java中线程池创建的几种方式的更多相关文章

  1. Java中线程池,你真的会用吗?

    在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...

  2. 沉淀再出发:java中线程池解析

    沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...

  3. Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor

    原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...

  4. Java 中线程池的 7 种创建方式!

    在 Java 语言中,并发编程都是通过创建线程池来实现的,而线程池的创建方式也有很多种,每种线程池的创建方式都对应了不同的使用场景,总体来说线程池的创建可以分为以下两类: 通过 ThreadPoolE ...

  5. Java中线程池的学习

    线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...

  6. Java中线程池的实现原理

    知识点总结 ---------------------------------------------------------------------------------------------- ...

  7. Java中线程池的实现原理-求职必备

    jdk1.5引入Executor线程池框架,通过它把任务的提交和执行进行解耦,只需要定义好任务,然后提交给线程池,而不用关心该任务是如何执行.被哪个线程执行,以及什么时候执行. 初始化线程池(4种) ...

  8. Java并发--线程间协作的两种方式:wait、notify、notifyAll和Condition

    在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界 ...

  9. java中线程池的几种实现方式

    1.线程池简介:    多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创建 ...

随机推荐

  1. 商业智能BI不仅仅是报表工具,它的真正价值是:决策支持

    作为一个独立系统,商业智能BI解决两个问题.一是信息的发布,它可以在正确的时间向正确的人提供正确的信息.几十年来,我们看到的商业智能项目,至少有90%的项目成果变成了提供信息的报告.这种情况下,改变的 ...

  2. 商业智能BI必备的特性

    商业智能BI的本质对企业来说,商业智能BI不能直接产生决策,而是利用BI工具处理后的数据来支持决策.核心是通过构建数据仓库平台,有效整合数据.组织数据,为分析决策提供支持并实现其价值. 传统的DW/O ...

  3. 【C# 程序集】C# assembly和module 根本区别

    相同点 两者都有:manifest.metadata.IL 不同点 1.assembly 有main程序函数.module只能附属于程序集,程序集可以拥有多个. 2.metadata的差异 程序集特有 ...

  4. elasticsearch7.8.0,kibana7.8.0安装

    目录 Windows下安装Elasticsearch Linux下安装Elasticsearch docker下安装Elasticsearch Kibana安装 chrome ElasticSearc ...

  5. vue结合webpack打包问题

    在使用vue开发项目时,如果要使用其单文件组件特性,必然要使用webpack或者其他打包工具打包,这里我用到的是webpack打包,首先是搭建vue环境和webpack环境,在这里遇到的一个问题是在成 ...

  6. JZ-045-扑克牌顺子

    扑克牌顺子 题目描述 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的 ...

  7. 接口自动化测试框架(Java 实现)

    目录 需求分析 开发设计 分层与抽象 技术选型 主要类设计 测试文件设计 工程目录设计 工程实现 github 地址 运行示例 需求分析 需求点 需求分析 通过 yaml 配置接口操作和用例 后续新增 ...

  8. 当.Net撞上BI可视化,这3种“套路”你必须知道

    最近葡萄在做技术支持,又遇到了客户给我们出的新问题. 事情是这样的. 这次客户使用的是.Net项目,直接做BI大屏过于复杂,所以想直接集成使用BI数据可视化分析大屏. 所以,这次我们就从--Wyn出发 ...

  9. 解决vue单页面应用做微信JSSDK注入权限时出现“invalid signature”(ios端)

    --都说微信开发多坑,没想到遇到一个天坑. 在做一个vue项目时,要用到微信JS-SDK,官方文档详见:https://developers.weixin.qq.com/doc/offiaccount ...

  10. powerful number筛

    心血来潮跑来实现以下这个东西 我们应该知道杜教筛的理论是 \(f * g=h\),那么问题在于如何找 \(g\). 之前的blog应该提到过可以令 \(g(p)=-f(p)\),这样一来 \(h\) ...