Java多线程 Callable和Future

Java多线程 Callable和Future

1、简介

(1)先来了解一下Callable 接口
Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。Callable接口的定义如下:

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Callable的类型参数是返回值的类型。例如:

Callable<Integer>表示一个最终返回Integer对象的异步计算。

(2)Future保存异步计算的结果。实际应用中可以启动一个计算,将Future对象交给某个线程,然后执行其他操作。Future对象的所有者在结果计算好之后就可以获得它。Future接口具有下面的方法:

public interface Future<V> {

   //可以用cancel方法取消该计算。如果计算还没有开始,它被取消且不再开始。
   //如果计算处于运行之中,那么如果mayInterrupt参数为true,它就被中断
    boolean cancel(boolean mayInterruptIfRunning);
    
    //判断是够被取消
    boolean isCancelled();
    
    //如果计算还在进行,isDone方法返回false;如果完成了,则返回true。
    boolean isDone();
    
    //调用被阻塞,直到计算完成
    V get() throws InterruptedException, ExecutionException;
    
    //设置等待时间,get方法的调用超时,抛出一个TimeoutException异常
    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

(3) FutureTask包装器是一种非常便利的机制,同时实现了Future和Runnable接口。FutureTask有2个构造方法

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

创建线程的步骤一般如下:
(1)创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例;

(2)使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值

(3)使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)

(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

2、使用

实例:

package callableTest;

import java.util.concurrent.*;
/**
* Callable与Future的应用
* Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现。
* Callable要采用ExecutorService的submit方法提交,返回的future对象可以取消  * 任务。
* CompletionService用于提交一组Callable任务,其take方法返回已完成的一个*Callable任务对应的Future对象。
*
**/
public class CallableTest {
    public static void main(String args[]) throws InterruptedException, ExecutionException {

        ExecutorService service = Executors.newSingleThreadExecutor();
        Future<String> future = service.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "hello world";
            }
        });
         System.out.println("等待结果中");
         System.out.println("得到的结果为:" + future.get());

        ExecutorService service2 = Executors.newFixedThreadPool(10);
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(service2);
        for(int i = 0; i < 10; ++i){
            final int temp = i;
            completionService.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return temp;
                }
            });
        }
        for(int i = 0; i < 10; ++i){
            System.out.println(completionService.take().get());
        }
        service.shutdown();
        service2.shutdown();
    }
}

结果:

等待结果中
得到的结果为:hello world
0
1
2
3
4
5
6
7
8
9
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值