JDK1.8 创建线程池有哪几种方式?

  • newFixedThreadPool

定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程

测试代码:

public class TestThreadPool {//定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程static ExecutorService fixedExecutor = Executors.newFixedThreadPool(3);public static void main(String[] args) {testFixedExecutor();}//测试定长线程池,线程池的容量为3,提交6个任务,根据打印结果可以看出先执行前3个任务,3个任务结束后再执行后面的任务private static void testFixedExecutor() {for (int i = 0; i < 6; i++) {final int index = i;fixedExecutor.execute(new Runnable() {public void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " index:" + index);}});}try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("4秒后...");fixedExecutor.shutdown();}}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-2 index:1
pool-1-thread-3 index:2
4秒后...
pool-1-thread-3 index:5
pool-1-thread-1 index:3
pool-1-thread-2 index:4
  • newCachedThreadPool

可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制

测试代码:

public class TestThreadPool {//可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制static ExecutorService cachedExecutor = Executors.newCachedThreadPool();public static void main(String[] args) {testCachedExecutor();}//测试可缓存线程池private static void testCachedExecutor() {for (int i = 0; i < 6; i++) {final int index = i;cachedExecutor.execute(new Runnable() {public void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " index:" + index);}});}try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("4秒后...");cachedExecutor.shutdown();}}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-6 index:5
pool-1-thread-5 index:4
pool-1-thread-4 index:3
pool-1-thread-3 index:2
pool-1-thread-2 index:1
4秒后...
  • newScheduledThreadPool

定长线程池,可执行周期性的任务

测试代码:

public class TestThreadPool {//定长线程池,可执行周期性的任务static ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(3);public static void main(String[] args) {testScheduledExecutor();}//测试定长、可周期执行的线程池private static void testScheduledExecutor() {for (int i = 0; i < 3; i++) {final int index = i;//scheduleWithFixedDelay 固定的延迟时间执行任务; scheduleAtFixedRate 固定的频率执行任务scheduledExecutor.scheduleWithFixedDelay(new Runnable() {public void run() {System.out.println(Thread.currentThread().getName() + " index:" + index);}}, 0, 3, TimeUnit.SECONDS);}try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("4秒后...");scheduledExecutor.shutdown();}}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-2 index:1
pool-1-thread-3 index:2
pool-1-thread-1 index:0
pool-1-thread-3 index:1
pool-1-thread-1 index:2
4秒后...
  • newSingleThreadExecutor

单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行

测试代码:

public class TestThreadPool {//单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行static ExecutorService singleExecutor = Executors.newSingleThreadExecutor();public static void main(String[] args) {testSingleExecutor();}//测试单线程的线程池private static void testSingleExecutor() {for (int i = 0; i < 3; i++) {final int index = i;singleExecutor.execute(new Runnable() {public void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " index:" + index);}});}try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("4秒后...");singleExecutor.shutdown();}}

打印结果:

pool-1-thread-1 index:0
4秒后...
pool-1-thread-1 index:1
pool-1-thread-1 index:2
  • newSingleThreadScheduledExecutor

单线程可执行周期性任务的线程池

测试代码:

public class TestThreadPool {//单线程可执行周期性任务的线程池static ScheduledExecutorService singleScheduledExecutor = Executors.newSingleThreadScheduledExecutor();public static void main(String[] args) {testSingleScheduledExecutor();}//测试单线程可周期执行的线程池private static void testSingleScheduledExecutor() {for (int i = 0; i < 3; i++) {final int index = i;//scheduleWithFixedDelay 固定的延迟时间执行任务; scheduleAtFixedRate 固定的频率执行任务singleScheduledExecutor.scheduleAtFixedRate(new Runnable() {public void run() {System.out.println(Thread.currentThread().getName() + " index:" + index);}}, 0, 3, TimeUnit.SECONDS);}try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("4秒后...");singleScheduledExecutor.shutdown();}}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-1 index:1
pool-1-thread-1 index:2
pool-1-thread-1 index:0
pool-1-thread-1 index:1
pool-1-thread-1 index:2
4秒后...
  • newWorkStealingPool

任务窃取线程池,不保证执行顺序,适合任务耗时差异较大。

线程池中有多个线程队列,有的线程队列中有大量的比较耗时的任务堆积,而有的线程队列却是空的,就存在有的线程处于饥饿状态,当一个线程处于饥饿状态时,它就会去其它的线程队列中窃取任务。解决饥饿导致的效率问题。

默认创建的并行 level 是 CPU 的核数。主线程结束,即使线程池有任务也会立即停止。

测试代码:

public class TestThreadPool {//任务窃取线程池static ExecutorService workStealingExecutor = Executors.newWorkStealingPool();public static void main(String[] args) {testWorkStealingExecutor();}//测试任务窃取线程池private static void testWorkStealingExecutor() {for (int i = 0; i < 10; i++) {//本机 CPU 8核,这里创建10个任务进行测试final int index = i;workStealingExecutor.execute(new Runnable() {public void run() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " index:" + index);}});}try {Thread.sleep(4000);//这里主线程不休眠,不会有打印输出} catch (InterruptedException e) {e.printStackTrace();}System.out.println("4秒后...");//      workStealingExecutor.shutdown();}}

打印结果如下,index:8,index:9并未打印出:

ForkJoinPool-1-worker-1 index:0
ForkJoinPool-1-worker-7 index:6
ForkJoinPool-1-worker-5 index:4
ForkJoinPool-1-worker-3 index:2
ForkJoinPool-1-worker-4 index:3
ForkJoinPool-1-worker-2 index:1
ForkJoinPool-1-worker-0 index:7
ForkJoinPool-1-worker-6 index:5
4秒后...

【Java面试题与答案】整理推荐

  • 基础与语法
  • 集合
  • 网络编程
  • 并发编程
  • Web
  • 安全
  • 设计模式
  • 框架
  • 算法与数据结构
  • 异常
  • 文件解析与生成
  • Linux
  • MySQL
  • Oracle
  • Redis
  • Dubbo

JDK1.8 创建线程池有哪几种方式?相关推荐

  1. 创建线程池有哪几种方式呢?

    转自: 创建线程池有哪几种方式呢? 下文笔者讲述创建线程池的方法分享,如下所示 java原生提供创建线程池的方式如下 newSingleThreadExecutor():它的特点在于工作线程数目被限制 ...

  2. 创建线程池有哪几种方式

    一.Executors Executors是一个线程相关的工具类.主要提供了以下几种创建线程池的方法: index method corePoolSize maximumPoolSize keepAl ...

  3. 44.创建线程池有哪几种方式?

    Executors.newFixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待: Executors.newCachedThreadPool:创建一个 ...

  4. 创建线程池有哪几种方式?

    线程池创建有七种方式,最核心的是最后一种: newSingleThreadExecutor():它的特点在于工作线程数目被限制为 1,操作一个无界的工作队列,所以它保证了所有任务的都是被顺序执行,最多 ...

  5. 为什么阿里巴巴禁止使用 Executors 创建线程池,而是通过 ThreadPoolExecutor 方式?...

    >>号外:关注"Java精选"公众号,菜单栏->聚合->干货分享,回复关键词领取视频资料.开源项目. 1. 通过Executors创建线程池的弊端 在创建线 ...

  6. 创建线程(Background Thread)的N种方式

    第一.Thread类 Thread类是实例化线程的主要方法:一个Thread实例管理一个线程,即执行序列.通过简单实例化一个对象,就可以创建一个线程,然后通过Thread对象提供的方法对线程进行管理. ...

  7. 【多线程】创建线程池有几种方式

    网上的文章一般会说,创建线程池基本上是2种方式.ThreadPoolExecutor或者Executors.本文就是通过剖析源码,看下它们的实现. ThreadPoolExecutor ThreadP ...

  8. threadpoolexecutor创建线程池_线程池ThreadPoolExecutor源码分析

    什么是线程池 创建线程要花费昂贵的资源和时间,如果任务来了才创建那么响应时间会变长,而且一个进程能创建的线程数量有限.为了避免这些问题,在程序启动的时候就创建若干线程来响应出来,它们被称为线程池,里面 ...

  9. Java创建线程池的几种方式

    方式一:继承Thread类 新建一个类并该类声明为Thread的子类. 这个子类应该重写run类的方法.例如,计算大于规定值的素数的线程可以写成如下: class PrimeThread extend ...

最新文章

  1. 【转】理解小波消失矩
  2. 使用 CoreDNS sidecar 来优化 Kubernetes Pod dns 性能
  3. python多线程多进程
  4. Makefile文件试错
  5. python语法报错_Python语法的常见错误和处理异常
  6. ubuntu卸载nvidia显卡驱动
  7. LeetCode每日一题——串联字符串的最大长度
  8. 解决安装多个Xcode出现的PBXProjectWizardChooserWizard问题
  9. 第2章企业管理中的经济学原理
  10. IDA Pro使用技巧及大杂烩
  11. JRebel设置快捷键+激活方式
  12. 关于SketchUp 2017版本安装之后一打开就会发送错误报告的问题
  13. 个人通过ipv6地址提供公网访问服务
  14. —— GPS测量原理及应用复习 ——
  15. 二项分布、poisson分布、gamma分布一些关系的笔记
  16. linux进阶52——pthread_cond_t
  17. 艰酸的试用期转正申请报告
  18. CVPR 2020 开幕!最佳论文奖等揭晓!
  19. 使用selenium解决12306的登录问题
  20. 华为java面试题目

热门文章

  1. 【Golang 基础系列九】Go 语言的枚举
  2. HTTP请求历险记(Go语言版) | Gopher Daily (2021.02.21) ʕ◔ϖ◔ʔ
  3. 有关H5将文字转成语音播放
  4. 知识人脉和经验究竟哪个是成功路上最重要的元素
  5. Windows系统telnet命令怎么打开?Telnet命令详解
  6. 第二届希玛眼科精准医疗国际会议圆满落幕!疑难眼病国际会诊·医生联盟正式启动...
  7. 梅西夺冠,一场精彩的比赛,一个时代的落幕
  8. 什么是多态(polymorphism)
  9. windows开机自动运行脚本
  10. 蓝桥杯2018国赛C++B组 换零钞(简单题)