zoukankan      html  css  js  c++  java
  • ExecutorCompletionService

    CompletionService和ExecutorCompletionService的实现

    使用executor提交任务,接收类型future.get()获取结果的顺序是线程执行先后的顺序。

    使用ExecutorCompletionService提交任务,CompletionService的take()方法接收future类型的返回值,获取的结果顺序是线程执行完毕的顺序

     JDK源码中CompletionService的javadoc说明如下:

    复制代码
    /**
     * A service that decouples the production of new asynchronous tasks
     * from the consumption of the results of completed tasks.  Producers
     * <tt>submit</tt> tasks for execution. Consumers <tt>take</tt>
     * completed tasks and process their results in the order they
     * complete. 
     */
    复制代码
    也就是说,CompletionService实现了生产者提交任务和消费者获取结果的解耦,生产者和消费者都不用关心任务的完成顺序,由CompletionService来保证,消费者一定是按照任务完成的先后顺序来获取执行结果。

    ExecutorCompletionService是CompletionService的实现,融合了线程池Executor和阻塞队列BlockingQueue的功能。
    复制代码
     public ExecutorCompletionService(Executor executor) {
            if (executor == null)
                throw new NullPointerException();
            this.executor = executor;
            this.aes = (executor instanceof AbstractExecutorService) ?
                (AbstractExecutorService) executor : null;
            this.completionQueue = new LinkedBlockingQueue<Future<V>>();
        }
    复制代码
    到这里可以推测,按照任务的完成顺序获取结果,就是通过阻塞队列实现的,阻塞队列刚好具有这样的性质:阻塞和有序。
     
    ExecutorCompletionService任务的提交和执行都是委托给Executor来完成。当提交某个任务时,该任务首先将被包装为一个QueueingFuture
    复制代码
    public Future<V> submit(Callable<V> task) {
            if (task == null) throw new NullPointerException();
            RunnableFuture<V> f = newTaskFor(task);
            executor.execute(new QueueingFuture(f));
            return f;
    }
    复制代码

    QueueingFuture是FutureTask的一个子类,通过改写FutureTask类的done方法,可以实现当任务完成时,将结果放入到BlockingQueue中。

    复制代码
    private class QueueingFuture extends FutureTask<Void> {
            QueueingFuture(RunnableFuture<V> task) {
                super(task, null);
                this.task = task;
            }
            protected void done() { completionQueue.add(task); }
            private final Future<V> task;
        }
    复制代码

    FutureTask.done(),这个方法默认什么都不做,就是一个回调,当提交的线程池中的任务完成时,会被自动调用。这也就说时候,当任务完成的时候,会自动执行QueueingFuture.done()方法,将返回结果加入到阻塞队列中,加入的顺序就是任务完成的先后顺序。

  • 相关阅读:
    Cassandra 分页 读取数据
    cassandra高级操作之索引、排序以及分页
    cassandra 可视化工具
    SpringBoot集成Cassandra参考文章
    022 android studio 首次启动时默认的sdk安装路径
    021 Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout)
    020 本机Gradle目录 Could not find com.android.tools.build:gradle:4.1
    019 Android Studio打开XML文件Design显示Waiting for build to finish
    018 Could not download espresso-core-3.2.0.aar (androidx.test.espresso:espresso-core:3.2.0)
    017 Android Studio is using the following JDK location when running Gradle:
  • 原文地址:https://www.cnblogs.com/itfeng813/p/14659345.html
Copyright © 2011-2022 走看看