线上问题:线程池拒绝策略「建议收藏」

线上问题:线程池拒绝策略「建议收藏」1场景复现服务调用时序如图1所示。中间件服务使用线程池ThreadPoolExecutor,配置丢弃策略为DiscardOldestPolicy(丢弃队列中等待最久的任务),队列容量为10。图1服务调用publicstaticExecutorServicethreadPoolExecutorGenerate=newThreadPoolExecutor(ThreadPoolConstant.CORE_THREAD_NUM,Thread

大家好,又见面了,我是你们的朋友全栈君。

1 场景复现

服务调用时序如图1所示。中间件服务使用线程池ThreadPoolExecutor,配置丢弃策略为DiscardOldestPolicy(丢弃队列中等待最久的任务),队列容量为10。
在这里插入图片描述


图1 服务调用

public static ExecutorService threadPoolExecutorGenerate = new ThreadPoolExecutor(
            ThreadPoolConstant.CORE_THREAD_NUM,
            ThreadPoolConstant.MAX_THREAD_NUM,
            ThreadPoolConstant.KEEP_ALIVE_TIME_SECONDS,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(ThreadPoolConstant.QUEUE_LENGTH),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortOldestPolicy());

2 原因

线程池配置丢弃策略为DiscardOldestPolicy(丢弃队列中等待最久的任务),队列容量为10,当队列达到上限时,丢弃任务,此时,后台服务无法获取到中间件丢弃任务的返回值,导致后台服务异常。

3 方案

中间件服务具有特殊性,必须要有返回值以确定当前任务是否正常,因此,使用线程池时,应该使用拒绝策略AbortPolicy,当拒绝任务后,抛出异常,在程序中捕获异常,并返回默认值或约定的值,保证中间件服务不会卡住,后台服务可以及时拿到数据,保证后台服务不会卡住。

3.1 AbortPolicy拒绝策略实现

public static class AbortPolicy implements RejectedExecutionHandler { 
   
        /** * Creates an {@code AbortPolicy}. */
        public AbortPolicy() { 
    }

        /** * Always throws RejectedExecutionException. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task * @throws RejectedExecutionException always */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 
   
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

3.2 完整配置

 public static ExecutorService threadPoolExecutorGenerate = new ThreadPoolExecutor(
            ThreadPoolConstant.CORE_THREAD_NUM,
            ThreadPoolConstant.MAX_THREAD_NUM,
            ThreadPoolConstant.KEEP_ALIVE_TIME_SECONDS,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(ThreadPoolConstant.QUEUE_LENGTH),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

4 小结

线程池策略:

  • 需要及时得到响应的服务,使用拒绝策略,捕获异常,及时返回默认值或约定值
  • 有补偿机制或无序及时处理的,可以使用丢弃策略。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/148619.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号