Java多线程--创建和使用线程池
使用线程池的目的
线程是稀缺资源,不能频繁的创建
解耦作用:线程的创建与执行完全分开,方便维护
将其放入一个池子中,可以给其他任务进行复用
优点
降低资源消耗,通过重复利用已创建的线程来降低线程创建和销毁造成的消耗。
提高相应速度,当任务到达时,任务可以不需要的等到线程创建就能立即执行。
提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅仅会消耗系统资源,还会降低体统的稳定性,使用线程可以进行统一分配,调优和监控
创建线程池的方式
在 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多线程--创建和使用线程池的更多相关文章
- java多线程总结五:线程池的原理及实现
1.线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创 ...
- (Java多线程系列九)线程池
线程池 1.什么是线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程.线程池中线程的数量通常取决于可用内存数量和应用程序的需求. ...
- Java多线程并发04——合理使用线程池
在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...
- java多线程详解(7)-线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系 ...
- java多线程(四)-自定义线程池
当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...
- java多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
- (CSDN迁移)JAVA多线程实现-单线程化线程池newSingleThreadExecutor
JAVA通过Executors提供了四种线程池,单线程化线程池(newSingleThreadExecutor).可控最大并发数线程池(newFixedThreadPool).可回收缓存线程池(new ...
- Java 多线程(五)—— 线程池基础 之 FutureTask源码解析
FutureTask是一个支持取消行为的异步任务执行器.该类实现了Future接口的方法. 如: 取消任务执行 查询任务是否执行完成 获取任务执行结果(”get“任务必须得执行完成才能获取结果,否则会 ...
- java核心-多线程(6)-线程池-ThreadPoolExecutor
1.java多线程编程少不了使用线程池,线程池相关的工具类所在jdk包,java.util.concurrent 2.使用示例 demo1 public class ThreadPoolDemo { ...
随机推荐
- maven命令下载jar包
mvn install:install-file -Dfile=jar包保存的本地路径 -DgroupId=jar保存的父级路径 -DartifactId=jar包文件夹名称 -Dversion=版本 ...
- Java--- 关于null的处理若干方法
Java--- 关于null的处理若干方法 相信空指针是平时最常见的错误了,下面认识 null ,有助于解决 NPE 问题. nulll大小写敏感 关于这个问题,其实是对面试时候手写算法题时候需要注意 ...
- IntelliJ IDEA 2019 的安装与破解
IDEA 全称 IntelliJ IDEA,是java编程语言开发的集成环境.IntelliJ在业界被公认为最好的java开发工具,尤其在智能代码助手.代码自动提示.重构.J2EE支持.各类版本工具( ...
- 元素的生于死(python里元素获取与删除)
今天被个元素烦着了,找了下网上也没啥直接详细的方法 就总结了下今天找过的方法,分享些简单的方法 直接放干货 删除篇 要删除列表元素的首次出现,只需要list.remove >>> a ...
- 架构设计 | 基于电商交易流程,图解TCC事务分段提交
本文源码:GitHub·点这里 || GitEE·点这里 一.场景案例简介 1.场景描述 分布式事务在业务系统中是十分常见的,最经典的场景就是电商架构中的交易业务,如图: 客户端通过请求订单服务,执行 ...
- CefSharp如何判断页面是否加载完
问题:CefSharp如何判断页面是否加载完毕. 摘要:相信C#用CefSharp做浏览器来发的应该有很多人都会有遇到这个问题.特别是要执行JavaScript的时候,涉及到跨页面的JavaScrip ...
- 【Spring注解驱动开发】AOP核心类解析,这是最全的一篇了!!
写在前面 昨天二狗子让我给他讲@EnableAspectJAutoProxy注解,讲到AnnotationAwareAspectJAutoProxyCreator类的源码时,二狗子消化不了了.这不,今 ...
- Linux常用命令--不断更新
Linux命令: !. 1.[root@loc8lhost/root]# 表示登陆进去系统,其中#是超级⽤用户也即root⽤用 户的系统提示符 #. 2.reboot命令可以重启系统 $. 3.关闭系 ...
- HDU - 5775-Bubble Sort(权值线段树)
P is a permutation of the integers from 1 to N(index starting from 1). Here is the code of Bubble So ...
- Easy Game(记忆化搜索)
You are playing a two player game. Initially there are n integer numbers in an array and player A an ...