java多线程 ThreadPoolExecutor 策略的坑
来源:互联网 发布:扭曲验证码识别 python 编辑:程序博客网 时间:2024/06/14 18:29
无论是使用jdk的线程池ThreadPoolExecutor 还是spring的线程池ThreadPoolTaskExecutor 都会使用到一个阻塞队列来进行存储线程任务。
当线程不够用时,则将后续的任务暂存到 阻塞队列中,等待有空闲线程来进行。
当这个阻塞队列满了的时候,会出现两种情况
正在运行的线程数量小于 maximumPoolSize,那么还是要创建线程运行这个任务;
正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会通过一个策略进行对后续的任务进行处理。
四种策略
ThreadPoolExecutor.AbortPolicy() 抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy() 重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy() 抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy() 抛弃当前的任务
其他很容易看出来,最近踩了一个ThreadPoolExecutor.CallerRunsPolicy()的坑。
情景是这样的:我需要通过线程进行创建长连接,当开启了15个线程的是,线程池最大即达到了maximumPoolSize的数量的时候,继续增大请求量,会无缘无故的多出来
一个长连接,由于有负载均衡,导致了很多请求无法从长连接中得到。
经过很长时间的测试,最终发现了是ThreadPoolExecutor.CallerRunsPolicy()策略导致的。
这个测试是当你的线程数达到最大,阻塞队列也满了的时候,之后的任务会强制先执行,但是没有了线程谁来执行呢,这个策略会强制中断主线程进行执行这个任务。
即是说,当我的量上来,线程池不够用的时候,中断了我的主线程,主线程没有长连接,就建立了一个新的长连接,那边进行了负载均衡,但是这边不会在进行主线程了,
导致很多请求接收不到。
假设队列大小为 10,corePoolSize 为 3,maximumPoolSize 为 6,那么当加入 20 个任务时,执行的顺序就是这样的:首先执行任务 1、2、3,然后任务 4~13 被放入队列。这时候队列满了,任务 14、15、16 会被马上执行,最终顺序是:1、2、3、14、15、16、4、5、6、7、8、9、10、11、12、13。
踩坑完毕
最终做法:
换成ThreadPoolExecutor.DiscardPolicy()策略,还是从已经建立的连接中进行 的到请求,不要继续创建连接。
- java多线程 ThreadPoolExecutor 策略的坑
- java多线程-ThreadPoolExecutor的拒绝策略RejectedExecutionHandler
- Java多线程之ThreadPoolExecutor
- Java多线程:ThreadPoolExecutor详解
- Java多线程:ThreadPoolExecutor详解
- Java多线程之ThreadPoolExecutor
- java多线程之ThreadPoolExecutor
- Java多线程:ThreadPoolExecutor详解
- java多线程之ThreadPoolExecutor
- Java多线程--ThreadPoolExecutor
- Java多线程:类ThreadPoolExecutor详解
- JAVA多线程之扩展ThreadPoolExecutor
- (十七)java多线程之ThreadPoolExecutor
- java 多线程之ThreadPoolExecutor参数设置
- Java多线程-线程池ThreadPoolExecutor的submit返回值Future
- Java多线程的调度策略
- Java的ThreadPoolExecutor(二)
- java 多线程 ThreadPoolExecutor 接收并处理数据
- 关于ajax 上传文件时parseRequest(request)为null的解决方法
- Codeforces 743 D Chloe and pleasant prizes
- java学习之路(3)- public class和class的理解
- vitamio窗口layout模式切换-全屏黑边问题
- dubbo的函数返回类,含有有参构造函数时,必须写明一个无参构造函数
- java多线程 ThreadPoolExecutor 策略的坑
- 深入理解 CyclicBarrier和CountDownLatch
- 使用for xml path()进行字符串拼接
- Hadoop开发入门踩过的坑(持续更新)
- JZOJ 3363 【NOI2013模拟】Number
- Redis 在新浪微博中的应用
- CSS font-family中文字体英文名称展示
- C4.5(weka又称为J48)算法原理详解
- Android中设计模式