【问题标题】:Is there no predefined saturation policy for ThreadPoolExecutor?ThreadPoolExecutor 没有预定义的饱和策略吗?
【发布时间】:2015-10-22 12:19:47
【问题描述】:

我正在阅读Java Concurrency in Practice,对下面关于ThreadPoolExecutor的说法感到困惑:

工作时没有预定义的饱和策略使执行阻塞 队列已满。

不过,作者也将abort 称为默认策略。

那么这里有什么问题?

【问题讨论】:

    标签: java threadpoolexecutor


    【解决方案1】:

    如 java 文档中所述:

    在方法execute(Runnable)中提交的新任务将被拒绝 Executor 已经关闭,并且当 Executor 使用 最大线程和工作队列容量的有限界限,并且是 饱和。在任何一种情况下,execute 方法都会调用 RejectedExecutionHandler.rejectedExecution(可运行, ThreadPoolExecutor) 方法的 RejectedExecutionHandler。

    还有 4 种不同的预定义处理程序:

    1. 在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序在拒绝时抛出运行时 RejectedExecutionException。
    2. 在 ThreadPoolExecutor.CallerRunsPolicy 中,调用 execute 本身的线程运行任务。这提供了一种简单的反馈控制机制,可以减慢新任务的提交速度。
    3. 在 ThreadPoolExecutor.DiscardPolicy 中,简单地丢弃了无法执行的任务。
    4. 在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果 executor 没有关闭,则丢弃工作队列头部的任务,然后重试执行(可能再次失败,导致重复。)

    所以默认使用 AbordPolicy。

    可以定义和使用其他类型的 RejectedExecutionHandler 类。这样做需要一些小心 特别是当政策被设计为仅在特定条件下起作用时 容量或排队政策。

    从 ThreadPoolExecutor 源代码中提取:

    /**
     * The default rejected execution handler
     */
    private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();
    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }
    
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }
    

    正如@Jiri Tousek 所说,所有这些默认行为都会阻止调用者。

    【讨论】:

    • 并与问题中的引用相关 - 四个预定义策略都不会阻止调用者。
    猜你喜欢
    • 1970-01-01
    • 2020-01-20
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    相关资源
    最近更新 更多