共计 2662 个字符,预计需要花费 7 分钟才能阅读完成。
jdk1.5 版本新增了
JUC
并发包,其中一个蕴含线程池。
四种回绝策略:
回绝策略类型 | 阐明 | |
---|---|---|
1 | ThreadPoolExecutor.AbortPolicy | 默认回绝策略,回绝工作并抛出工作 |
2 | ThreadPoolExecutor.CallerRunsPolicy | 应用调用线程间接运行工作 |
3 | ThreadPoolExecutor.DiscardPolicy | 间接回绝工作,不抛出谬误 |
4 | ThreadPoolExecutor.DiscardOldestPolicy | 触发回绝策略,只有还有工作新增,始终会抛弃阻塞队列的最老的工作,并将新的工作退出 |
事后配置
配置线程池。
- 外围线程和最大线程都尽量设置的小一点,别离设置成 1 和 2
- 阻塞队列设置 固定长度 的有界队列,长度为 1
- 线程工厂设置 默认线程工厂
// 外围线程数
int corePoolSize = 1;
// 最大线程数
int maximumPoolSize = 2;
// 线程存活工夫
long keepAliveTime = 10;
// 线程存活工夫单位
TimeUnit unit = TimeUnit.SECONDS;
// 有界队列 遵循 FIFO 准则
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1);
// 线程工厂
ThreadFactory threadFactory = Executors.defaultThreadFactory();
创立线程工作
创立线程工作,一个线程工作执行一秒:
class TaskThread implements Runnable{
private int i;
public TaskThread(int i) {this.i = i;}
@Override
public void run() {
try {TimeUnit.SECONDS.sleep(2);
System.out.println("执行工作:" + i);
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
回绝策略一:AbortPolicy
默认回绝策略,回绝工作并抛出工作
// 回绝策略 默认回绝策略,回绝工作并抛出异样:RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler);
for (int i = 1; i <= 5; i++) {
try {threadPool.execute(new TaskThread(i));
} catch (Exception e) {System.out.println("【工作" + i + "】报错:" + e.getMessage());
}
}
输入
【工作】4 报错:Task com.test.controller.ThreadPoolController$TaskThread@5c0369c4 rejected from java.util.concurrent.ThreadPoolExecutor@50675690[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]【工作】5 报错:Task com.test.controller.ThreadPoolController$TaskThread@31b7dea0 rejected from java.util.concurrent.ThreadPoolExecutor@50675690[Running, pool size = 2, active threads = 2, queued tasks = 1, completed tasks = 0]
执行工作:1
执行工作:3
执行工作:2
最大线程数 + 阻塞队列 = 3,执行到 4,5 的时候就抛出谬误。这里须要用 try catch
捕捉异样。工作 1、2、3 失常执行。
如果提交的工作都要执行,能够将抛出的谬误工作存入在 redis 中,而后定时从
redis
中获取工作,再提交执行。
回绝策略二:CallerRunsPolicy
调用线程运行多余的工作。
更换回绝策略,将下面的 AbortPolicy
换成 CallerRunsPolicy
。
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
执行工作,输入:
执行工作:1
执行工作:4
执行工作:3
执行工作:2
执行工作:5
最大线程数 + 阻塞队列 = 3,多余的工作还是持续被执行。
回绝策略三:DiscardPolicy
回绝工作,不会抛出谬误。
更换策略,将CallerRunsPolicy
换成DiscardPolicy
:
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
执行工作,输入:
执行工作:1
执行工作:3
执行工作:2
多余的线程工作提交被回绝,而只执行 最大线程数 + 阻塞队列 数量的工作,并且不会抛出谬误。
回绝策略四:DiscardOldestPolicy
只有还有工作新增,始终会抛弃 阻塞队列 的最老的工作,并将新的工作退出到 阻塞队列中 。
更换策略,将DiscardPolicy
换成DiscardOldestPolicy
:
RejectedExecutionHandler handler3 = new ThreadPoolExecutor.DiscardOldestPolicy();
执行工作,输入:
执行工作:3
执行工作:1
执行工作:5
工作的执行程序是 外围线程数 —> 阻塞队列 —> 最大线程数,其中工作 1,工作 3 提交胜利。
- 工作 2 因为在阻塞队列中,
- 前面的工作 4 把工作 2 挤掉,
- 工作 5 又把工作 4 挤掉,所以最初执行的是工作 5。
总结
本文介绍了线程四种回绝策略,当工作工作大于 最大线程 + 阻塞队列 会执行阻塞队列。
- AbortPolicy 默认策略,回绝工作,并抛出异样
- CallerRunsPolicy 调用线程执行对于的工作
- DiscardPolicy 回绝工作,不会抛出异样
- DiscardOldestPolicy 有多余的工作,把阻塞队列最老的工作抛弃,放入新的工作,直到没有新的工作。
如果感觉文章对你有帮忙的话,请点个赞吧!
正文完