20.custom自定义线程池
自定义线程池
1.若Executors工厂类无法满足需求,可以自己使用工厂类创建线程池,底层都是使用了ThreadPoolExecutor这个类可以自定义。
public ThreadPoolExecutor(int corePoolSize(当前核心线程数),int maximunPoolSize(最大线程数),long keepAliveTime(保持活跃时间),TimeUnit utin(时间单位),BlockingQueue<Runnable> workQueue(线程队列容器),ThreadFactory threadFactory(线程工厂),RejectedExecutionHandler rejectedExecutionHandler(拒绝执行的方法,线程队列阻塞到容器等待、例:限制最大执行、));
则会将任务加入队 列中,若队列已经满,则在总线程数不大于maximumPoolSize(最大coreRoolSize数)的前提下。创建一个新的线程,若大于 maximumPoolSize则实行拒绝策略、或其他处理方式。
implements RejectedExecutionHandle
package demo8.threadPool;import java.util.concurrent.*;public class CustomThreadPool1 {/* 有界队列ArrayBlockingQueue:若有新的线程需要执行,日光线程池实际数小于"coreRoolSize",则优先参加线程,若大于,则会将任务加入队列中,若队列已经满,则在总线程数不大于maximumPoolSize(最大coreRoolSize数)的前提下。创建一个新的线程,若大于maximumPoolSize则实行拒绝策略、或其他处理方式。*/public static void main(String[] args) {BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(3);ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,2,60,TimeUnit.SECONDS,blockingQueue);UserTask userTask1 = new UserTask(1, "任务-1");UserTask userTask2 = new UserTask(2, "任务-2");UserTask userTask3 = new UserTask(3, "任务-3");UserTask userTask4 = new UserTask(4, "任务-4");UserTask userTask5 = new UserTask(5, "任务-5");threadPoolExecutor.execute(userTask1);threadPoolExecutor.execute(userTask2);threadPoolExecutor.execute(userTask3);threadPoolExecutor.execute(userTask4);threadPoolExecutor.execute(userTask5);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}threadPoolExecutor.shutdown();}}输出:pool-1-thread-1 run taskId:1这种情况处理完所有的任务
pool-1-thread-2 run taskId:5
pool-1-thread-2 run taskId:3
pool-1-thread-1 run taskId:2
pool-1-thread-2 run taskId:4
package demo8.threadPool;/*** Created by liudan on 2017/7/23.*/public class UserTask implements Runnable {private int id;private String taskName;@Overridepublic void run() {try {Thread.sleep(1000);System.err.println(Thread.currentThread().getName()+"\t run taskId:"+this.getId());} catch (InterruptedException e) {e.printStackTrace();}}public UserTask() {}public UserTask(int id, String taskName) {this.id = id;this.taskName = taskName;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTaskName() {return taskName;}public void setTaskName(String taskName) {this.taskName = taskName;}@Overridepublic String toString() {return "UserTask{" +"id=" + id +'}';}}
案例2:拒绝任务,超出暂缓任务对了大小
public static void main(String[] args) {BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(3);ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,2,60,TimeUnit.SECONDS,blockingQueue);UserTask userTask1 = new UserTask(1, "任务-1");UserTask userTask2 = new UserTask(2, "任务-2");UserTask userTask3 = new UserTask(3, "任务-3");UserTask userTask4 = new UserTask(4, "任务-4");UserTask userTask5 = new UserTask(5, "任务-5");UserTask userTask6 = new UserTask(6, "任务-6");多加一个threadPoolExecutor.execute(userTask1);threadPoolExecutor.execute(userTask2);threadPoolExecutor.execute(userTask3);threadPoolExecutor.execute(userTask4);threadPoolExecutor.execute(userTask5);threadPoolExecutor.execute(userTask6);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}threadPoolExecutor.shutdown();}输出:Exception in thread "main" java.util.concurrent.RejectedExecutionException:Task UserTask{id=6} rejected from java.util.concurrent.ThreadPoolExecutor@6f94fa3e[Running, pool size = 2, active threads = 2, queued tasks = 3, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
at demo8.threadPool.CustomThreadPool1.main(CustomThreadPool1.java:35)
pool-1-thread-1 run taskId:1
pool-1-thread-2 run taskId:5
pool-1-thread-1 run taskId:2
pool-1-thread-2 run taskId:3
pool-1-thread-1 run taskId:4
package demo8.threadPool;import java.util.concurrent.RejectedExecutionHandler;import java.util.concurrent.ThreadPoolExecutor;public class CustomDiscardPolicy implements RejectedExecutionHandler {public CustomDiscardPolicy() {}@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.err.println("拒绝任务");/*** 用日志记录保存下,可做后续的扩展操作*/System.err.println("加入任务log...\t"+r.toString());}}
public static void main(String[] args) {BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(3);ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,2,60,TimeUnit.SECONDS,blockingQueue,new CustomDiscardPolicy());//使用自定义拒绝策略UserTask userTask1 = new UserTask(1, "任务-1");UserTask userTask2 = new UserTask(2, "任务-2");UserTask userTask3 = new UserTask(3, "任务-3");UserTask userTask4 = new UserTask(4, "任务-4");UserTask userTask5 = new UserTask(5, "任务-5");UserTask userTask6 = new UserTask(6, "任务-6");threadPoolExecutor.execute(userTask1);threadPoolExecutor.execute(userTask2);threadPoolExecutor.execute(userTask3);threadPoolExecutor.execute(userTask4);threadPoolExecutor.execute(userTask5);threadPoolExecutor.execute(userTask6);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}threadPoolExecutor.shutdown();}输出:拒绝任务
加入任务log... UserTask{id=6}
pool-1-thread-1 run taskId:1
pool-1-thread-2 run taskId:5
pool-1-thread-1 run taskId:2
pool-1-thread-2 run taskId:3
pool-1-thread-1 run taskId:4
package demo8.threadPool;import java.util.concurrent.*;public class CustomThreadPool2 {/* 无界队列LinkedBlockingQueue:与有界队列相比,除非系统资源耗尽,否则无界的任务队列不存在加入任务队列失败的情况下,当有新的任务到来,系统的线程数小于coreRoolSize时候,则新建线程执行任务,当到达coreRoolSize后就不会增加了,若后续还有新的任务加入,而且没有空闲的线程资源,则任务直接进入队列等待。若任务创建和处理速度差异很大,无界队列保持快速增长,知道耗尽系统内存。*/public static void main(String[] args) throws InterruptedException {BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>();ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,10,120L, TimeUnit.SECONDS,blockingQueue);//ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(4);for (int i=1;i<=20;i++){threadPoolExecutor.execute(new UserTask(i,"任务-"+i));}Thread.sleep(1000);System.err.println("blockingQueue size:"+blockingQueue.size());Thread.sleep(2000);}}输出:pool-1-thread-1 run taskId:1
pool-1-thread-2 run taskId:2
pool-1-thread-3 run taskId:3
pool-1-thread-4 run taskId:4
pool-1-thread-5 run taskId:5
blockingQueue size:10
pool-1-thread-2 run taskId:7
pool-1-thread-4 run taskId:9
pool-1-thread-3 run taskId:8
pool-1-thread-1 run taskId:6
pool-1-thread-5 run taskId:10
pool-1-thread-2 run taskId:11
pool-1-thread-1 run taskId:14
pool-1-thread-3 run taskId:13
pool-1-thread-4 run taskId:12
pool-1-thread-5 run taskId:15
pool-1-thread-1 run taskId:17
pool-1-thread-4 run taskId:19
pool-1-thread-5 run taskId:20
pool-1-thread-2 run taskId:16
pool-1-thread-3 run taskId:18
20.custom自定义线程池的更多相关文章
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
- 一个自定义线程池的小Demo
在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...
- C#自定义线程池
自定义线程池-c#的简单实现 下面是代码,希望大家提出更好的建议: 1.ThreadManager.cs using System; using System.Threading; using Sys ...
- SOFA 源码分析 — 自定义线程池原理
前言 在 SOFA-RPC 的官方介绍里,介绍了自定义线程池,可以为指定服务设置一个独立的业务线程池,和 SOFARPC 自身的业务线程池是隔离的.多个服务可以共用一个独立的线程池. API使用方式如 ...
- Spring Boot使用@Async实现异步调用:自定义线程池
前面的章节中,我们介绍了使用@Async注解来实现异步调用,但是,对于这些异步执行的控制是我们保障自身应用健康的基本技能.本文我们就来学习一下,如果通过自定义线程池的方式来控制异步调用的并发. 定义线 ...
- SpringBoot 自定义线程池
本教程目录: 自定义线程池 配置spring默认的线程池 1. 自定义线程池 1.1 修改application.properties task.pool.corePoolSize=20 task.p ...
- SpringBoot 自定义线程池,多线程
原文:https://www.jianshu.com/p/832f2b162450 我们都知道spring只是为我们简单的处理线程池,每次用到线程总会new 一个新的线程,效率不高,所以我们需要自定义 ...
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- Android 自定义线程池的实战
前言:在上一篇文章中我们讲到了AsyncTask的基本使用.AsyncTask的封装.AsyncTask 的串行/并行线程队列.自定义线程池.线程池的快速创建方式. 对线程池不了解的同学可以先看 An ...
随机推荐
- 【PAT】1005. 继续(3n+1)猜想 (25)
1005. 继续(3n+1)猜想 (25) 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中 ...
- Nuxt 2.0 需要将pug-loader改成pug-plain-loader
Nuxt 2.0 需要将pug-loader改成pug-plain-loader npm i pug-plain-loader -D 解决问题!! 参考链接 https://my.oschina.ne ...
- 【LOJ】#2174. 「FJOI2016」神秘数
题解 这道题的结论很显然= = 就是暴力求的话,把一个区间的数排一下序,如果当前这个数大于前面所有数的前缀和+1,那么前缀和+1即我们所求的答案 那么我们设置一个当前答案(初始为1),在主席树上求出来 ...
- HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模
Multiply game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- EOJ 3247 铁路修复计划
二分,最小生成树. 二分一下$k$,然后每次算最小生成树验证即可,事实证明,$cmp$函数,参数用引用还是能提高效率的,不引用一直$TLE$,时限有点卡常. 然后错误的代码好像$AC$了啊,$L$和$ ...
- 洛谷——P2393 yyy loves Maths II
P2393 yyy loves Maths II 题目背景 上次蒟蒻redbag可把yyy气坏了,yyy说他只是小学生,蒟蒻redbag这次不坑他了. 题目描述 redbag给了yyy很多个数,要yy ...
- 外行人都能看懂的SpringCloud
一.前言 只有光头才能变强 认识我的朋友可能都知道我这阵子去实习啦,去的公司说是用SpringCloud(但我觉得使用的力度并不大啊~~)... 所以,这篇主要来讲讲SpringCloud的一些基础的 ...
- css去除chrome下select元素默认border-radius
在mac下的chrome,对于select元素会默认有一个border-radius,当然有些情况下并不需要圆角,所以就要去掉. 比较常用的方法是: .select { -webkit-appeara ...
- Scrapy实战篇(七)之Scrapy配合Selenium爬取京东商城信息(下)
之前我们使用了selenium加Firefox作为下载中间件来实现爬取京东的商品信息.但是在大规模的爬取的时候,Firefox消耗资源比较多,因此我们希望换一种资源消耗更小的方法来爬取相关的信息. 下 ...
- 【UOJ #206】【APIO 2016】Gap
http://uoj.ac/problem/206 对于T=1,直接从两端往中间跳可以遍历所有的点. 对于T=2,先求出最小值a和最大值b,由鸽巢原理,答案一定不小于\(\frac{b-a}{N-1} ...