Java关于线程池的使用
一、四种线程池创建的方式
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
查看源码发现,在创建这四种线程池都是通过ThreadPoolExecutor来实现的。
推荐:(摘取阿里技术规范)
线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 各个方法的弊端:
1)newFixedThreadPool 和 newSingleThreadExecutor:
主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。
2)newCachedThreadPool 和 newScheduledThreadPool:
主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。
二、实战
简单不说了,网上都有,页面底部也有推荐的资料。
接下来,直接使用Spring中的线程池来展示,大多的项目中都会用到Spring,所以就可能会使用ThreadPoolTaskExecutor。
1.首先,配置线程池的属性
itom.parseAsyncTaskExecutor.corePoolSize=10
itom.parseAsyncTaskExecutor.maxPoolSize=100
itom.parseAsyncTaskExecutor.queueCapacity=200
itom.parseAsyncTaskExecutor.keepAliveSeconds=300
itom.parseAsyncTaskExecutor.rejectedExecutionHandler=
java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy
2.applicationContext-itom.xml中配置Bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="true" default-autowire="byName">
<!--线程池-->
<bean id="threadPoolTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!--核心线程数,默认为1 -->
<property name="corePoolSize" value="${itom.parseAsyncTaskExecutor.corePoolSize}" />
<!--最大线程数,默认为Integer.MAX_VALUE -->
<property name="maxPoolSize" value="${itom.parseAsyncTaskExecutor.maxPoolSize}" />
<!--队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE -->
<property name="queueCapacity" value="${itom.parseAsyncTaskExecutor.queueCapacity}" />
<!--线程池维护线程所允许的空闲时间,默认为60s -->
<property name="keepAliveSeconds" value="${itom.parseAsyncTaskExecutor.keepAliveSeconds}" />
<!--线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 -->
<property name="rejectedExecutionHandler">
<!--AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 -->
<!--CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,
可以有效降低向线程池内添加任务的速度 -->
<!--DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
<!--DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 -->
<bean class="${itom.parseAsyncTaskExecutor.rejectedExecutionHandler}" />
</property>
</bean>
</beans>
3.在实现的service中直接使用
@Service("itomService")
public class ItomServiceImpl implements ItomService{
@Autowired
private LoginService loginService;
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Override
public void calc(final String userId, final String sourceCode) {
threadPoolTaskExecutor.execute(new Runnable() {
@Override
public void run() {
...
}
});
}
}
4.在类里面直接使用:(根据需要,定制相应的线程池)
private static final ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(100),
new ThreadPoolExecutor.AbortPolicy());
四种线程池的使用:
http://cuisuqiang.iteye.com/blog/2019372
关于线程池框架写得比较全的:
http://blog.csdn.net/tuke_tuke/article/details/51353925
ThreadPoolExecutor的介绍(属性的信息):
http://blog.xiaohansong.com/2016/07/12/java-executor/
其他:
(Executor、ExecutorService、ThreadPoolExecutor的区别)
http://blog.csdn.net/linghu_java/article/details/17123057
补充一片写到我认为是重点的博客:
http://gityuan.com/2016/01/16/thread-pool/
Java关于线程池的使用的更多相关文章
- 深入理解Java之线程池
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
- Java中线程池的学习
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...
- java利用线程池处理集合
java利用线程池处理集合 2018年07月23日 17:21:19 衍夏成歌 阅读数:866 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/s ...
- 深入理解Java之线程池(爱奇艺面试)
爱奇艺的面试官问 (1) 线程池是如何关闭的 (2) 如何确定线程池的数量 一.线程池销毁,停止线程池 ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown() ...
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
- [转]深入理解Java之线程池
原文链接 原文出处: 海 子 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这 ...
- 沉淀再出发:java中线程池解析
沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...
- Java并发--线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...
- Java进阶——— 线程池的原理分析
前言 在了解线程池之前,其实首先出现的疑问是:为什么要使用线程池,其次是了解什么是线程池,最后是如何使用线程池,带着疑问去学习. 为什么要使用 前面多线程文章中,需要使用线程就开启一个新线程,简单方便 ...
- Java调度线程池ScheduleExecutorService(续)
链接 Java线程池详解(一) Java线程池详解(二) Java调度线程池ScheduleExecutorService 上面列出了最近写的关于java线程池ScheduleExecutorServ ...
随机推荐
- webpack的理解、总结
weabpck的基础应用 https://blog.zhangjd.me/2016/06/19/webpack-your-bags/ https://juejin.im/post/5cc26dfef2 ...
- go语言从例子开始之Example33.工作池
在这个例子中,我们将看到如何使用 Go 协程和通道实现一个工作池 . Example: package main import "fmt" import "time&qu ...
- mysql授予权限
grant show databases on *.* to 'asg'@'%'; grant select on *.* to 'asg'@'%'; grant show view on *.* t ...
- PF_INET 与驱动
https://blog.csdn.net/trustnature/article/details/7849562 ? ? ?
- 《Spring Boot实战》笔记(目录)
目录 目 录第一部分 点睛Spring 4.x第1 章 Spring 基础 .............................................................. ...
- oracle的分析函数over
参考地址:https://www.cnblogs.com/chinas/p/7058771.html?utm_source=itdadao&utm_medium=referral#_lab2_ ...
- [BZOJ5305] [HAOI2018] 苹果树 数学 组合计数
Summary 题意很清楚: 小 \(C\) 在自己家的花园里种了一棵苹果树, 树上每个结点都有恰好两个分支. 经过细心的观察, 小 \(C\) 发现每一天这棵树都会生长出一个新的结点. 第一天的时候 ...
- 25.Java锁的深度化
Java锁的深度化 悲观锁.乐观锁.排他锁 场景 当多个请求同时操作数据库时,首先将订单状态改为已支付,在金额加上200,在同时并发场景查询条件下,会造成重复通知. SQL: Update 悲观锁与乐 ...
- python 的文件编码处理
python的文件编码处理有点粗鲁 1.不管文件原来是编码类型,读入后都转换成Unicode的编码 2.写入文件时,write函数把变量以读入文件的编码方式写入(根据open(path,mode,en ...
- sql 2008查看进程情况和对应语句,检查死锁进程
---------------------------------进程情况1----------------------- --得到SPID if object_id('tempdb..#info') ...