callable和CompletionService接口试用

CompletionService接口定义为Interface CompletionService<V>接口定它在java7中只有一个实现ExecutorCompletionService,这个接口内部集成了一个BlockingQueue,因此可以实现对多线程运行结果的收集工作。为了更好的测试该接口,我使用了两个测试,第一个测试是自己定义一个外部BlockingQueue来接收callable返回的数据。第二个测试是用CompletionService对executor进行装饰,使得返回的CompletionService对象能直接submit任务。

但是我发现它submit的后并没有马上调用executor的submit,而是对它进行了封装,因此出现了一点点延迟。如果在submit之后使用shutdown()命令结束的话,实际上该task可能还没有 放到executor的taskpool中。所以这一点值得注意。

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;

public class testCallable {
    public static void main(String[] args) {
        try {
            futureCount();
            completionServiceCount();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用自定义阻塞队列得到任务执行结果
     *
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public static void futureCount() throws InterruptedException,
            ExecutionException {
        BlockingQueue<Future<Integer>> queue = new LinkedBlockingDeque<Future<Integer>>();
        ExecutorService executorService = Executors.newCachedThreadPool();
        int threadNum = 5;
        for (int i = 0; i < threadNum; i++) {
            Future<Integer> future = executorService.submit(getTask());
            queue.put(future);
        }
        int sum = 0;
        int temp = 0;
        while(!queue.isEmpty()){
            temp = queue.take().get();
            sum += temp;
            System.out.print(temp + "\t");
        }
        System.out.println("BlockingQueue all is : " + sum);
        executorService.shutdown();
    }

    /**
     * 使用completionService收集callable结果
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void completionServiceCount() throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(
                executorService);
        int threadNum = 5;
        for (int i = 0; i < threadNum; i++) {
            completionService.submit(getTask());
        }
        int sum = 0;
        int temp = 0;
        for(int i=0;i<threadNum;i++){
            temp = completionService.take().get();
            sum += temp;
            System.out.print(temp + "\t");
        }
        System.out.println("CompletionService all is : " + sum);
        executorService.shutdown();
    }

    public static Callable<Integer> getTask() {
        final Random rand = new Random();
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int num = 0;
                for (int i = 0; i < 10; i++) {
                    num = num + rand.nextInt(10);
                }
                return num;
            }
        };
        return task;
    }
}
时间: 2024-08-10 12:40:29

callable和CompletionService接口试用的相关文章

Executor框架(六)CompletionService 接口

??CompletionService 接口是一个独立的接口,并没有扩展 ExecutorService . 其默认实现类是ExecutorCompletionService; ??接口 CompletionService 的功能是:以异步的方式一边执行未完成的任务,一边记录.处理已完成任务的结果.从而可以将 任务的执行 与 处理任务的执行结果 分离开来.简单来说,CompletionService 就是监视着 Executor线程池执行的任务,用 BlockingQueue 将完成的任务的结果

Callable与Runable接口 submit与execute区别

execute(Runnable x) 没有返回值.可以执行任务,但无法判断任务是否成功完成. submit(Runnable x) 返回一个future.可以用这个future来判断任务是否成功完成. 在Java5之后,任务分两类:一类是实现了Runnable接口的类,一类是实现了Callable接口的类. 两者都可以被ExecutorService执行 Future future = pool.submit(new RunnableTest("Task2"));         

Java并发编程-Executor框架之Callable和Future接口

在上一篇文章中我们已经了解了Executor框架进行线程管理,这篇文章将学习Executor框架的另一个特性,我们知道执行Runnable任务是没有返回值得,但Executor可以运行并发任务并获得返回值,Concurrent包提供下面两个接口实现这个功能: Callable接口:这个接口声明call(),类似于Runnable的run(),可以在这个方法里实现任务的具体逻辑操作.Callable是一个泛型接口,必须声明call()的返回类型. Future接口:这个接口声明了一下方法来获取Ca

Callable 和 Future接口 学习

* Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务. * Callable和Runnable有几点不同: * (1)Callable规定的方法是call(),而Runnable规定的方法是run(). * (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的. * (3)call()方法可抛出异常,而run()方法是不能抛出异常的. * (4)运行Callable任务可拿到一个Futu

基于java callable及future接口解决生产者消费者问题

这两天复习java线程时,把java里面的线程基本知识点与jdk1.5以后新添加的一些类的使用都了解了一下,借用生产者消费者的问题来将他们实践一下. 题目:(题目在csdn一大牛的空间找的) 生产者-消费者模式,这个食堂中只有1张桌子,同时最多放10个盘子,现在有4个厨师做菜,每做好一盘就往桌子上放(生产者将产品往仓库中放),而有6个食客不停地吃(消费者消费产品,为了说明问题,他们的食量是无的).一般而言,厨师200-400ms做出一盘菜,而食客要400-600ms吃完一盘.当桌子上放满了10个

Java多线程之~~~Callable接口获得返回值

ThreadPoolExecutor提供了另一个非常强有力的接口,那就是callable.这个接口和runnable类似,但是实现这个 接口的方法是call方法,这个方法是可以返回值的,弥补了runnable不能返回值的悲哀.而且这个方法可以配合ThreadP oolExecutor使用,获得Future接口,从这个接口的名字我们就能知道,返回的这个类似于指向这个线程的一个指针,我 们能通过这个Future接口知道当前线程的运行情况,包括是否已经完成任务,目前运行情况,运行完成后的返回值等, 而

【多线程学习记录一(2)】继承Thread类和实现Runnable接口、Callable接口的区别

1)Runnable和Callable同是接口 * Callable的任务执行后可返回值,而Runnable的任务是不能返回值(是void);call方法可以抛出异常,run方法不可以 * 运行Callable任务可以拿到一个Future对象,表示异步计算的结果.它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果.通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果. * 加入线程池运行,Runnable使用ExecutorService的execute方

线程池的应用及Callable接口的使用

Java代码   public interface Executor { /** * Executes the given command at some time in the future.  The command * may execute in a new thread, in a pooled thread, or in the calling * thread, at the discretion of the <tt>Executor</tt> implementa

Java多线程之Callable接口的实现

import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /*  * 一.创建执行线程的方式三:实现 Callable 接口. 相较于实现 Runnable 接口的方式,方法可以有返回值,并且可以抛出异常.  *  * 二.执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运