Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么拒绝处理程序不';当队列溢出且所有线程都忙时调用_Java_Multithreading_Concurrency_Threadpool_Threadpoolexecutor - Fatal编程技术网

Java 为什么拒绝处理程序不';当队列溢出且所有线程都忙时调用

Java 为什么拒绝处理程序不';当队列溢出且所有线程都忙时调用,java,multithreading,concurrency,threadpool,threadpoolexecutor,Java,Multithreading,Concurrency,Threadpool,Threadpoolexecutor,我已经阅读了java文档中关于ThreadPoolExecutor的手册: 让我们看看这一部分: 被拒绝的任务 方法execute(java.lang.Runnable)中提交的新任务将被删除 当执行者被关闭时被拒绝,并且当 Executor对最大线程和工作队列都使用有限边界 容量,并且已饱和。在这两种情况下,execute方法都会调用 RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, 它的java.util.concu

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

让我们看看这一部分:

被拒绝的任务

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

  • 在默认ThreadPoolExecutor.AbortPolicy中,处理程序抛出 拒绝时运行时拒绝ExecutionException
  • 在ThreadPoolExecutor.CallerRunPolicy中,调用 execute本身运行任务。这提供了一个简单的反馈 控制机制,可降低新任务的执行速度 提交
  • 在ThreadPoolExecutor.DiscardPolicy中,无法执行的任务 只是简单地放弃了
  • 在ThreadPoolExecutor.DiscardOldestPolicy中,如果 执行器未关闭,位于工作队列顶端的任务已关闭 删除,然后重试执行(可能再次失败, 导致重复此操作。) 可以定义和使用其他类型的 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();
    
    我希望在控制台中看到“拒绝”输出


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

    新的ArrayBlockingQueue(1)
    可以容纳一个可运行的队列。
    第三次调用
    threadPoolExecutor.execute(runnable)
    应该会得到预期的结果。由于第一个呼叫立即从队列中删除,第二个呼叫在队列中保留,直到第一个
    可运行
    完成执行。

    新阵列锁定队列(1)
    可以保留一个可运行的呼叫。 第三次调用
    threadPoolExecutor.execute(runnable)
    应该会得到预期的结果。因为第一个呼叫立即从队列中删除,第二个呼叫在队列中保持,直到第一个
    runnable
    完成执行

    work  started
    work  finished
    work  started
    work  finished