大佬教程收集整理的这篇文章主要介绍了线程池的拒绝策略,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
为什么要设计池
抵消每次获取资源产生的消耗,这种池的设计会初始预设资源,可类比食堂打饭,类似的池设计有线程池、jdbc连接池等,跟池有关的特征包括:池子的初始值、最大值、活跃值等线程池什么时候触发拒绝策略
一般是超过池的最大值时触发,但线程连接池还有一个阻塞队列缓冲区,当前提交任务数大于(maxPoolSize + queueCapacity)时就会触发线程池的拒绝策略了。线程池有哪几种拒绝策略
一般线程池都是通过RejectedExecutionHandler接口中的rejectedExecution方法实现拒绝策略,一般有四种拒绝策略,分别对应不用方法策略 public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor E) {
if (!e.isShutdown()) {
r.run();
}
}
}
当线程池满了后,此拒绝策略会把线程丢给调用者自己处理,适用于对时间要求不高,但是不允许失败的场景 2. AbortPolicy
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor E) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
线程池的默认拒绝策略,使用任何场景,但是使用时应注意处理好抛出的异常,可能会打断当前执行 3. DiscardPolicy
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor E) {
}
}
没使用,就是超出了就不管 4. DiscardOldestPolicy
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor E) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
把最先进入队列的线程抛弃,这个策略使用于消息更新,永远是最新的消息最需要
public class AbortPolicyWithReport extends ThreadPoolExecutor.AbortPolicy {
protected static final Logger logger = LoggerFactory.getLogger(AbortPolicyWithReport.class);
private final String threadName;
private final URL url;
private static volatile long lastPrintTime = 0;
private static Semaphore guard = new Semaphore(1);
public AbortPolicyWithReport(String threadName, URL url) {
this.threadName = threadName;
thiS.Url = url;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor E) {
String msg = String.format("Thread pool is EXHAUSTED!" +
" Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: %d)," +
" Executor status:(isShutdown:%s, isTerminated:%s, isTerminaTing:%s), in %s://%s:%d!",
threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(), e.getLargestPoolSize(),
e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminaTing(),
url.getProtocol(), url.getIp(), url.getPort());
logger.warn(msg);
dumpJStack();
throw new RejectedExecutionException(msg);
}
private void dumpJStack() {
//省略实现
}
}
可以看到,当dubbo的工作线程触发了线程拒绝后,主要做了三个事情,原则就是尽量让使用者清楚触发线程拒绝策略的真实原因
以上是大佬教程为你收集整理的线程池的拒绝策略全部内容,希望文章能够帮你解决线程池的拒绝策略所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。