java中CompletionService的使用

简介: java中CompletionService的使用

java中CompletionService的使用


之前的文章中我们讲到了ExecutorService,通过ExecutorService我们可以提交一个个的task,并且返回Future,然后通过调用Future.get方法来返回任务的执行结果。


这种方式虽然有效,但是需要保存每个返回的Future值,还是比较麻烦的,幸好ExecutorService提供了一个invokeAll的方法,来保存所有的Future值,我们看一个具体的实现:


public void useExecutorService() throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        Callable<String> callableTask = () -> {
            TimeUnit.MILLISECONDS.sleep(300);
            return "Task's execution";
        };
        List<Callable<String>> callableTasks = new ArrayList<>();
        callableTasks.add(callableTask);
        callableTasks.add(callableTask);
        callableTasks.add(callableTask);
        List<Future<String>> futures = executor.invokeAll(callableTasks);
        executor.shutdown();
    }


上面的例子中,我们定义了3个task,通过调用executor.invokeAll(callableTasks)返回了一个 List<Future>,这样我们就可以得到所有的返回值了。


除了上面的invokeAll方法外,我们今天要介绍一个CompletionService接口。


CompletionService实际上是ExecutorService和BlockingQueue的结合体,ExecutorService用来提交任务,而BlockingQueue用来保存封装成Future的执行结果。


通过调用take和poll的方法来获取到Future值。


CompletionService是一个接口,我们看下它的一个具体实现ExecutorCompletionService:


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作为参数。


我们看下上面的例子如果用ExecutorCompletionService重写是怎么样的:


public void useCompletionService() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletionService<String> completionService=new ExecutorCompletionService<String>(executor);
        Callable<String> callableTask = () -> {
            TimeUnit.MILLISECONDS.sleep(300);
            return "Task's execution";
        };
        for(int i=0; i< 5; i ++){
            completionService.submit(callableTask);
        }
        for(int i=0; i<5; i++){
            Future<String> result=completionService.take();
            System.out.println(result.get());
        }
    }


上面的例子通过completionService.submit来提交任务,通过completionService.take()来获取结果值。


其实CompletionService还有一个poll的方法,poll和take的区别在于:take如果获取不到值则会等待,而poll则会返回null。


本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/CompletionService

相关文章
|
6月前
|
Java
Java 并发编程 Future及CompletionService
Java 并发编程 Future及CompletionService `Future`用于异步结果计算。它提供了一些方法来检查计算是否完成,使用`get`方法将阻塞线程直到结果返回 `CompletionService`整合了`Executor`和`BlockingQueue`的功能。将`Callable`任务提交给它去执行,使用`take()`和`poll()`获取最新完成的任务执行结果.
Java 并发编程 Future及CompletionService
|
Java
【Java深层系列】「并发编程系列」让我们一起探索一下CompletionService的技术原理和使用指南
【Java深层系列】「并发编程系列」让我们一起探索一下CompletionService的技术原理和使用指南
72 0
【Java深层系列】「并发编程系列」让我们一起探索一下CompletionService的技术原理和使用指南
|
存储 Java
【Java技术指南】「并发编程专题」CompletionService框架基本使用和原理探究(基础篇)
【Java技术指南】「并发编程专题」CompletionService框架基本使用和原理探究(基础篇)
168 0
|
Java
Java多线程 CompletionService和ExecutorCompletionService
Java多线程 CompletionService和ExecutorCompletionService
143 0
Java多线程 CompletionService和ExecutorCompletionService
|
Java API
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(下)
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(下)
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(下)
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(中)
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(中)
|
缓存 Java
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(上)
【小家Java】Future、FutureTask、CompletionService、CompletableFuture解决多线程并发中归集问题的效率对比(上)
|
Java 数据采集 容器
Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll(转)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/27250059 一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runnable是一种有很大局限的抽象,run方法中只能记录日志,打印,或者把数据汇总入某个容器(一...
1348 0
|
Java 数据采集 容器
Java并发专题 带返回结果的批量任务执行 CompletionService
转自 :http://blog.csdn.net/lmj623565791/article/details/27250059 一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runnable是一种有很大局限的抽象,run方法中只能记录日志,打印,或者把数据汇总入某个容器(一方面内存消耗大,另一方面需要控制同步,效率很大的限制),总之不能返回执行的结果;比如同时
2135 0
|
7天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
下一篇
无影云桌面