【问题标题】:Why rejection handler doesn't invoke when queue overflowed and all threads busy为什么当队列溢出并且所有线程都忙时拒绝处理程序不调用
【发布时间】:2017-07-17 23:56:57
【问题描述】:

我已阅读 java 文档中关于 ThreadPoolExecutor 的手册:

让我们看看这部分:

被拒绝的任务

在方法 execute(java.lang.Runnable) 中提交的新任务将是 当 Executor 已关闭时被拒绝,并且也 当 执行器对最大线程和工作队列都使用有限的界限 容量,并且已饱和。 在任何一种情况下,execute 方法都会调用 RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法的它 拒绝执行处理程序。四个预定义的处理程序策略是 提供:

  1. 在默认的 ThreadPoolExecutor.AbortPolicy 中,处理程序会抛出一个 拒绝时出现运行时 RejectedExecutionException。
  2. 在 ThreadPoolExecutor.CallerRunsPolicy 中,调用的线程 execute 本身运行任务。这提供了一个简单的反馈 控制机制将减慢新任务的速度 已提交。
  3. 在 ThreadPoolExecutor.DiscardPolicy 中,无法执行的任务 被简单地丢弃了。
  4. 在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果 executor 没有关闭,工作队列头部的任务是 删除,然后重试执行(可能再次失败, 导致重复。) 可以定义和使用其他类型的 RejectedExecutionHandler 类。这样做需要一些小心 特别是当政策被设计为仅在特定条件下起作用时 容量或排队政策。

为了检查粗体文本,我试着写一个小例子:

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<Runnable>(1),
                Executors.defaultThreadFactory(),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.out.println("rejected");
                    }
                });
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("work  started");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("work  finished");
            }
        };
        //execute
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.execute(runnable);
        threadPoolExecutor.shutdown();

此代码输出:

work  started
work  finished
work  started
work  finished

我希望在控制台中看到“被拒绝”的输出。

你能解释一下这种行为吗?

【问题讨论】:

    标签: java multithreading concurrency threadpool threadpoolexecutor


    【解决方案1】:

    new ArrayBlockingQueue&lt;Runnable&gt;(1) 可以容纳一个 runnable。 第三次致电threadPoolExecutor.execute(runnable) 应该会给您预期的结果。由于第一个调用立即从队列中删除,第二个调用保留在队列中,直到第一个 runnable 完成执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多