线程池(三)拒绝策略
线程池(三)拒绝策略
程序员朱永胜有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准
https://blog.zysicyj.top
可点击链接
https://blog-1253652709.cos.ap-guangzhou.myqcloud.com//picgo/202401180921373.png
解答疑问
线程池的拒绝策略
线程池(ThreadPoolExecutor)是 Java 中用于管理和执行异步任务的一个强大工具。然而,在高并发场景下,线程池中的任务队列可能会被填满,从而导致新的任务无法被提交。这时,线程池就需要处理这些无法处理的任务。线程池的拒绝策略(RejectedExecutionHandler)就是为了解决这个问题而设计的。
1. 线程池的拒绝策略简介
Java 的线程池提供了四种内置的拒绝策略,分别是:
- AbortPolicy:直接抛出
RejectedExecutionException
,阻止系统正常工作。 - CallerRunsPolicy:由调用线程处理该任务。
- DiscardPolicy:直接丢弃任务,不予任何处理。
- DiscardOldestPolicy:丢弃队列中最旧的未处理任务,然后尝试重新提交被拒绝的任务。
2. 详细源码解析
接下来,我们通过源码深入了解每一种拒绝策略的具体实现。
2.1 AbortPolicy
1 | public static class AbortPolicy implements RejectedExecutionHandler { |
解析:
- AbortPolicy策略会直接抛出
RejectedExecutionException
异常,通知调用者任务被拒绝,并且不会执行该任务。 - 这种策略适合对任务丢失敏感的场景,确保调用者能感知到任务未被执行。
2.2 CallerRunsPolicy
1 | public static class CallerRunsPolicy implements RejectedExecutionHandler { |
解析:
- CallerRunsPolicy策略不会丢弃任务,而是由提交任务的线程去执行该任务。
- 这种策略可以有效降低向线程池提交任务的速度,适合需要降低任务提交速率的场景。
2.3 DiscardPolicy
1 | public static class DiscardPolicy implements RejectedExecutionHandler { |
解析:
- DiscardPolicy策略在任务被拒绝时直接丢弃该任务,不进行任何处理,也不会抛出异常。
- 这种策略适合不需要确保每个任务都被执行的场景,比如日志记录等。
2.4 DiscardOldestPolicy
1 | public static class DiscardOldestPolicy implements RejectedExecutionHandler { |
解析:
- DiscardOldestPolicy策略会丢弃队列中最旧的未处理任务,然后尝试重新提交被拒绝的任务。
- 这种策略适合优先处理最新任务的场景。
3. 自定义拒绝策略
除了以上四种内置策略,开发者还可以实现 RejectedExecutionHandler
接口,定义自己的拒绝策略。以下是一个自定义拒绝策略的示例:
1 | public class CustomRejectPolicy implements RejectedExecutionHandler { |
4. 总结
线程池的拒绝策略在高并发场景下尤为重要。根据具体应用场景选择合适的拒绝策略,可以有效地控制系统的稳定性和任务处理效率。了解并掌握这些策略的实现原理,有助于开发者在实际项目中灵活运用。
通过上述内容,我们详细解析了 Java 线程池的四种内置拒绝策略的源码实现及其适用场景。希望这些内容能帮助你更好地理解和应用线程池的拒绝策略。