线程池的四种拒绝策略

今天写线程池的时候由于设定了最大线程数,需要写拒绝策略,顺便就把4中拒绝策略记录一下!

1.AbortPolicy:ThreadPoolExecutor中默认的拒绝策略就是AbortPolicy。直接抛出异常也不处理

private static final RejectedExecutionHandler defaultHandler =  new 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());
    }
}

2.CallerRunsPolicy:CallerRunsPolicy在任务被拒绝添加后,会调用当前线程池的所在的线程去执行被拒绝的任务。

实现:

public static class CallerRunsPolicy implements RejectedExecutionHandler {
    public CallerRunsPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        if (!e.isShutdown()) {
            r.run();
        }
    }
}

3.DiscardPolicy:采用这个拒绝策略,会让被线程池拒绝的任务直接抛弃,不会抛异常也不会执行。

实现:

public static class DiscardPolicy implements RejectedExecutionHandler {
    public DiscardPolicy() { }
    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    }
}

4.DiscardOldestPolicy: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);
        }
    }
}

### Java 线程池四种拒绝策略及其实现方式与应用场景 Java 线程池通过 `RejectedExecutionHandler` 接口定义了线程池在无法处理新任务时的行为。以下详细说明四种内置拒绝策略的实现方式及适用场景。 #### 1. **AbortPolicy(中止策略)** AbortPolicy 的实现方式是直接抛出 `RejectedExecutionException` 异常,拒绝新任务的提交[^1]。这种方式适用于对系统的稳定性要求较高,且不希望丢失任务的场景。例如,在实时数据处理系统中,任务的丢失可能导致不可恢复的数据错误,因此需要立即发现并处理异常情况[^2]。 代码示例: ```java ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.AbortPolicy() ); ``` #### 2. **CallerRunsPolicy(调用者运行策略)** CallerRunsPolicy 的特点是将被拒绝的任务交由调用者线程执行[^1]。这种策略可以避免任务的丢失,但可能会导致提交任务的线程阻塞,从而降低系统的整体吞吐量。适用于负载较低时,避免任务丢失的场景。 代码示例: ```java ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.CallerRunsPolicy() ); ``` #### 3. **DiscardPolicy(丢弃策略)** DiscardPolicy 的实现方式是默默丢弃无法处理的任务,不抛出任何异常[^1]。这种方式适用于可以容忍任务丢失的情况,例如处理非关键日志或缓存更新等任务[^2]。 代码示例: ```java ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.DiscardPolicy() ); ``` #### 4. **DiscardOldestPolicy(丢弃最旧策略)** DiscardOldestPolicy 的特点是丢弃任务队列中最旧的未处理任务,然后尝试将新任务加入队列重新执行[^1]。这种方式适用于任务的重要性相对较低,且希望尽量处理新提交任务的场景[^2]。 代码示例: ```java ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, new ThreadPoolExecutor.DiscardOldestPolicy() ); ``` ### 总结 每种拒绝策略都有其特定的适用场景。选择合适的拒绝策略需要根据任务的重要性和系统的容错能力进行权衡。AbortPolicy 和 CallerRunsPolicy 更适合任务不能丢失的场景,而 DiscardPolicy 和 DiscardOldestPolicy 则适用于可以容忍任务丢失的场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值