线程池自带的那些拒绝策略

今天被边上的小伙伴问到如果线程池处理不过来,但是队列又是个有界队列的时候该怎么办,害得我又翻了半天书重看了下线程池的相关内容。哎,有些东西一段时间不用之后就有可能忘了,所以趁这个机会来深入了解下JDK1.8线程池的拒绝策略,其实也蛮简单的。

 

线程池的拒绝策略有如下四种:

AbortPolicy:丢弃任务并抛出RejectedExecutionException异常 (默认)

DiscardPolicy:也是丢弃任务,但是不抛出异常

DiscardOldestPolicy:丢弃队列最前面的任务,执行后面的任务

CallerRunsPolicy:由调用线程处理该任务 

 

 拒绝策略在线程池执行任务的execute()方法中用到,有两处地方:

  1. 线程池此时不处于running状态,调用拒绝策略拒绝任务
  2. 线程池创建新的Worker失败,调用拒绝策略拒绝任务

 

这些拒绝策略都实现了RejectedExecutionHandler接口,该接口只有一个方法:

void rejectedExecution(Runnable r, ThreadPoolExecutor executor);

注意这个接口返回的是void

 

 

下面来逐个看下这些拒绝策略的源码:

AbortPolicy:

源码中就直接throw了一个异常

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    throw new RejectedExecutionException("Task " + r.toString() +
                                         " rejected from " +
                                         e.toString());
}

 

DiscardPolicy:

...更简单,方法里面是个空,即抛弃掉任务并且什么都不做

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}

 

DiscardOldestPolicy

也很简单,如果线程池没有shutdown,那么就讲队列中的任务poll出来一个(对于这个任务什么也不做,就是丢弃掉了最早的任务);然后在调用execute()方法执行刚提交的任务(扔到队列里面)。

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        e.getQueue().poll();
        e.execute(r);
    }
}

 

 

CallerRunsPolicy

最流弊的是这个...让提交任务的线程自己来执行(前提是线程池没有shutdown)。哈哈,看到这个策略,发现自己好像又学到了一点。

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
        r.run();//让提交任务的线程自己run,hhh
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值