Java和Spring中线程池创建方法
一、线程池定义
1.JDK中线程池类图
Executor:父接口,所有线程池都实现了这个接口,里面有一个excute()方法用于执行线程
ExecutorService:线程池接口,继承自Executor接口,供了生命周期管理的方法,返回 Future 对象,可以返回执行完的结果
ThreadPoolExecutor:线程池的具体实现类,一般使用ThreadPoolExecutor创建线程池
2.创建线程池的工具类
Executors:线程池的工具类,用于创建线程池,返回ExecutorService类型的线程池
1)public static ExecutorService newFiexedThreadPool(int Threads) :创建固定数目线程的线程池
2)public static ExecutorService newCachedThreadPool():创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程
3)public static ExecutorService newSingleThreadExecutor():创建一个单线程化的Executor
4)public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):调度型线程池
3.区别
1)Executor 接口定义了 execute()
方法用来接收一个Runnable
接口的对象,不接受返回的对象,而 ExecutorService 接口中的 submit()
方法可以通过Future 对象接受Runnable
和Callable
接口的对象
2)ExecutorService 还提供用来控制线程池的方法。比如:调用 shutDown()
方法终止线程池
3)Executors 类提供工厂方法用来创建不同类型的线程池
4.线程池参数
corePoolSize:核心线程数
maximumPoolSize, //最大线程数
keepAliveTime:当线程数超过核心线程数,线程的最大存活时间
unit:keepAliveTime的时间单位
workQueue:阻塞队列
threadFactory: 创建线程的工厂
handler:拒绝策略
5.线程池执行顺序
1)当线程数小于 corePoolSize
时,创建线程执行任务。
2)当线程数大于等于 corePoolSize
并且 workQueue
没有满时,放入workQueue
中
3)线程数大于等于 corePoolSize
并且当 workQueue
满时,新任务新建线程运行,线程总数要小于 maximumPoolSize
4)当线程总数等于 maximumPoolSize
并且 workQueue
满了的时候执行 handler
的 rejectedExecution
。也就是拒绝策略
6.拒绝访问策略
ThreadPoolExecutor默认有四个拒绝策略:
1、ThreadPoolExecutor.AbortPolicy()
直接抛出异常RejectedExecutionException
2、ThreadPoolExecutor.CallerRunsPolicy()
直接调用run方法并且阻塞执行
3、ThreadPoolExecutor.DiscardPolicy()
直接丢弃后来的任务
4、ThreadPoolExecutor.DiscardOldestPolicy()
丢弃在队列中队首的任务
当然可以自己继承RejectedExecutionHandler来写拒绝策略.
二、线程池使用方法
1.Java JDK创建线程池的方法-ThreadPoolExecutor
1)使用ThreadPoolExecutor创建线程池
API如下所示:
public ThreadPoolExecutor(int corePoolSize, //核心线程数int maximumPoolSize, //最大线程数long keepAliveTime, //当线程数超过核心线程数,线程的最大存活时间TimeUnit unit, //keepAliveTime的时间单位BlockingQueue<Runnable> workQueue) //阻塞队列容量{ this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);
}
所在包:java.util.concurrent.*
2)代码实现:
3)结果展示:
2.Spring创建线程池方式-ThreadPoolTaskExecutor
所在包:package org.springframework.core.task;
创建线程池并注入spring容器,开启@EnableAsync注解方便后续使用它@Async异步化调用
@Configuration
@EnableAsync
public class BeanConfig {@Beanpublic ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();// 设置核心线程数executor.setCorePoolSize(5);// 设置最大线程数executor.setMaxPoolSize(10);// 设置队列容量executor.setQueueCapacity(20);// 设置线程活跃时间(秒)executor.setKeepAliveSeconds(60);// 设置默认线程名称executor.setThreadNamePrefix("hello-");// 设置拒绝策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 等待所有任务结束后再关闭线程池executor.setWaitForTasksToCompleteOnShutdown(true);return executor;}
}
3.异步调用线程池线程方法-ThreadPoolTaskExecutor
1)代码处使用
需要使用@Autowired装配获取注入的线程池对象
@Autowiredprivate ThreadPoolTaskExecutor executor;
/*** 根据活动id获取指定活动,异步添加缓存操作*/@RequestMapping("/test9")public String testTaskExecutor() throws Throwable {log.info("进入方法:");//异步调用executor.execute(() -> {try {log.info("进入异步方法:");Thread.sleep(2000);jedisClusterClient.getJedisCluster().set("test9:async", "test");
} catch (InterruptedException e) {e.printStackTrace();}System.out.println("异步执行添加缓存:" + jedisClusterClient.getJedisCluster().get("test9:async"));});log.info("方法执行完毕");return "test";}
执行结果:
可以看到异步执行是在方法执行完毕后才执行的,不是同步的,异步化成功
2)使用@Async注解异步调用
注意:@Async修饰的方法的实例必须注入spring容器中方能使用,代码如下:
异步方法使用@Async调用:
执行结果:
可以看到结果也是异步化调用
Java和Spring中线程池创建方法相关推荐
- java线程池之一:创建线程池的方法
在Java开发过程中经常需要用到线程,为了减少资源的开销,提高系统性能,Java提供了线程池,即事先创建好线程,如果需要使用从池中取即可,Java中创建线程池有以下的方式, 1.使用ThreadPoo ...
- Android中网络请求创建单个线程池的方法
创建单个线程池的方法 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; impor ...
- Java中线程池,你真的会用吗
转载自 Java中线程池,你真的会用吗 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Ex ...
- java中线程池的几种实现方式
1.线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 ...
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
- async spring 默认线程池_SpringBoot中Async异步方法和定时任务介绍
1.功能说明 Spring提供了Async注解来实现方法的异步调用.即当调用Async标识的方法时,调用线程不会等待被调用方法执行完成即返回继续执行以下操作,而被调用的方法则会启动一个独立线程来执行此 ...
- Java队列——线程池创建的例子
线程池为线程生命周期开销问题和资源不足问题提供了解决方案.通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上.其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟.这 ...
- [Java高并发系列(5)][详细]Java中线程池(1)--基本概念介绍
1 Java中线程池概述 1.1 什么是线程池? 在一个应用当中, 我们往往需要多次使用线程, 这意味着我们需要多次创建和销毁线程.那么为什么不提供一个机制或概念来管理这些线程呢? 该创建的时候创建, ...
- java构造单例线程池_java中常见的六种线程池详解
之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如 ...
最新文章
- 2021全球最具影响力 AI 学者榜单: 中国占比11.1%,位列第二
- python 操作微信定时发信息
- 2021-05-10 如何修改Docker的默认镜像存储位置
- linux 学习教程
- 中科燕园GIS外包-----基于ArcGIS的应急平台
- 网络:NAT使用场景
- 舒适的路线(codevs 1001)
- NoSQL数据库的介绍、NoSQL的产品、NoSQL数据库的分类等;
- matlab产生窄带高斯随机过程,窄带随机过程的产生及其性能测试
- python处理复杂excel_python高手之路python处理excel文件(方法汇总)
- zhuan [讲解] OI 字符串 常用哈希方法(by sxy sxy)
- html 列表 表格 form表单 文本域 label
- ASDFZ 3633 -- 排兵布阵
- 图像尺寸与Rect适配
- 2017免费发布信息平台排行大全!
- winbugs MATLAB,winbugs问题求教:
- restapi是什么意思_网上整理的对于Rest和Restful api的理解
- 神州租车,致力于提供更加便利的出行方式
- Python网络爬虫数据采集实战:Scrapy框架爬取QQ音乐存入MongoDB
- 开源:Taurus.MVC 框架
热门文章
- 家用笔记本电脑什么牌子好_家用什么牌子的吸尘器好?
- 期末考试前的预习,科目:化工设备与反应器(4)
- 四十二、MOOC课程 | Python中的Scipy模块
- ​从熵不变性看Attention的Scale操作
- 学习历史预测未来,国防科大新模型实现未来事实预测SOTA
- Funnel-Transformer:让Transformer更高效地处理长序列
- 直播报名 | CUDA优化:高性能库cuBLAS使用指南
- 深度协同过滤:用神经网络取代内积建模
- 求取给定的二叉树的镜像_17---二叉树的镜像
- mysql安装后创建,Mysql安装创建删除