使用线程池的目的

  • 线程是稀缺资源,不能频繁的创建

  • 解耦作用:线程的创建与执行完全分开,方便维护

  • 将其放入一个池子中,可以给其他任务进行复用

优点

  • 降低资源消耗,通过重复利用已创建的线程来降低线程创建和销毁造成的消耗。

  • 提高相应速度,当任务到达时,任务可以不需要的等到线程创建就能立即执行。

  • 提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅仅会消耗系统资源,还会降低体统的稳定性,使用线程可以进行统一分配,调优和监控

创建线程池的方式

 在 JDK 1.5 之后推出了相关的 api,常见的创建线程池方式有以下三种:

  • Executors.newCachedThreadPool():无限线程池,线程池动态扩容

  • Executors.newFixedThreadPool(nThreads):创建固定大小的线程池

  • Executors.newSingleThreadExecutor():创建单个线程的线程池

  • Executors.newScheduledThreadPool():定时执行的线程池

 JDK1.8新增

  • Executors.newWorkStealingPool(): newWorkStealingPool适合使用在很耗时的操作,但是newWorkStealingPool不是ThreadPoolExecutor的扩展,它是新的线程池类ForkJoinPool的扩展,但是都是在统一的一个Executors类中实现,由于能够合理的使用CPU进行对任务操作(并行操作),所以适合使用在很耗时的任务中

但是在阿里巴巴开发规约中对线程池的创建有以下几个强制要求:

可以看到规约是不允许使用Executors直接创建线程池的,而要通过ThreadPoolExecutor的方式创建

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

我们看到这三种方式的源码也是通过ThreadPoolExecutor的方式来创建的,接下来我们看一下ThreadPoolExecutor的API

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 线程工厂,可以自定义线程名称
  • handler 当队列和最大线程池都满了之后的拒绝策略

    • AbortPolicy:处理程序遭到拒绝将抛出运行时 RejectedExecutionException
    • CallerRunsPolicy:线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度
    • DiscardPolicy:不能执行的任务将被删除
    • DiscardOldestPolicy:如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)

工作原理

  • 当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程

  • 当线程池达到corePoolSize时,新提交任务将被放入 workQueue 中,等待线程池中任务调度执行

  • 当workQueue已满,且 maximumPoolSize 大于 corePoolSize 时,新提交任务会创建新线程执行任务

  • 当提交任务数超过 maximumPoolSize 时,新提交任务由 RejectedExecutionHandler 处理

  • 当线程池中超过corePoolSize 线程,空闲时间达到 keepAliveTime 时,关闭空闲线程

  • 当设置allowCoreThreadTimeOut(true) 时,线程池中 corePoolSize 线程空闲时间达到 keepAliveTime 也将关闭

线程池大小创建的原则

  • IO 密集型任务:由于线程并不是一直在运行,所以可以尽可能的多配置线程,比如 CPU 个数 * 2

  • CPU 密集型任务(大量复杂的运算)应当分配较少的线程,比如 CPU 个数相当的大小

附:SpringBoot线程池工具类

Java多线程--创建和使用线程池的更多相关文章

  1. java多线程总结五:线程池的原理及实现

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

  2. (Java多线程系列九)线程池

    线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...

  3. Java多线程并发04——合理使用线程池

    在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...

  4. java多线程详解(7)-线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系 ...

  5. java多线程(四)-自定义线程池

    当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...

  6. java多线程系列六、线程池

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...

  7. (CSDN迁移)JAVA多线程实现-单线程化线程池newSingleThreadExecutor

    JAVA通过Executors提供了四种线程池,单线程化线程池(newSingleThreadExecutor).可控最大并发数线程池(newFixedThreadPool).可回收缓存线程池(new ...

  8. Java 多线程(五)—— 线程池基础 之 FutureTask源码解析

    FutureTask是一个支持取消行为的异步任务执行器.该类实现了Future接口的方法. 如: 取消任务执行 查询任务是否执行完成 获取任务执行结果(”get“任务必须得执行完成才能获取结果,否则会 ...

  9. java核心-多线程(6)-线程池-ThreadPoolExecutor

    1.java多线程编程少不了使用线程池,线程池相关的工具类所在jdk包,java.util.concurrent 2.使用示例 demo1 public class ThreadPoolDemo { ...

随机推荐

  1. ASP.Net中的async+await异步编程

    在.NET Framework4.5框架.C#5.0语法中,通过async和await两个关键字,引入了一种新的基于任务的异步编程模型(TAP).在这种方式下,可以通过类似同步方式编写异步代码,极大简 ...

  2. Reinforcement learning in artificial and biological systems

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 在生物和人工系统的学习研究之间,已经有富有成果的概念和想法流.Bush and Mosteller,Rescorla a ...

  3. Windows server 2008 搭建DNS服务

    现在用Windows搭建DNS的已经很少了,感觉也只有一些公司的某块部分能用上,最近在捣鼓这个,索性直接写下来,以后可以看了直接用. 开始: ★★★配置静态IP地址 老样子,有关服务器功能的建立,都是 ...

  4. 一文带你深扒ClassLoader内核,揭开它的神秘面纱!

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! 前言 Clas ...

  5. 焦大:做SEO应该研究的用户需求的方向

    http://www.wocaoseo.com/thread-60-1-1.html 最近收到打击很大,收获也颇多,这一切都莫过于用户需求的问题.我曾经给我弟说过,我对检索排名特征识别.提取和计算自认 ...

  6. 滑动窗口(Sliding Window)技巧总结

    什么是滑动窗口(Sliding Window) The Sliding Problem contains a sliding window which is a sub – list that run ...

  7. vim编辑器 与etc目录

    第1章         目录结构 1.1  vim  vim故障 vim  是vi的升级版本 vi类似于文本文档  vim类似于notepad++ 编辑 必须先安装vim命令 yum -y insta ...

  8. 【洛谷日报#26】GCC自带位运算系列函数

    文章转自 洛谷 谈到GCC的黑科技,大家想到的一定是这句: #pragma GCC optimize (3)//吸氧 抑或是这句: #pragma GCC diagnostic error " ...

  9. 记录laravelchina中的微信小程序教程的npm install安装报错

    npm安装报错时 npm ERR! code EIOnpm ERR! syscall symlinknpm ERR! path ../@babel/parser/bin/babel-parser.js ...

  10. Visual Studio Installer闪退问题解决方法

    Visual Studio 2019安装推荐的方式是通过官方给的Installer进行的(2017也是同样方法),但是有时会出现在”即将完成…一切即将准备就绪“这个界面闪退的问题,导致软件的安装.卸载 ...