java多线程学习笔记(5)

本文详细介绍了Java中Callable接口的call()方法,其区别于Runnable,并阐述了Future接口的作用,包括取消任务、检查任务状态和获取异步结果。讲解了FutureTask的使用方法,无论是自定义Callable还是使用线程池,以及如何通过Future获取计算结果。
摘要由CSDN通过智能技术生成

java多线程学习笔记(5)–Callable和Future

13、Callable和Future

Callable接口声明了一个名称为call()的方法,同时这个方法可以有返回值V,也可以抛出异常,这是其与Runnable接口不同的地方

Future接口是用来获取异步计算结果的,是对具体的Runnable或者Callable对象任务执行的结果进行获取(get()),取消(cancel()),判断是否完成等操作。

Future相关类的继承关系:

FutureTask

Future接口方法

//取消任务的执行。参数指定是否立即中断任务执行,或者等等任务结束
boolean cancel(boolean mayInterruptIfRunning)
//任务是否已经取消,任务正常完成前将其取消,则返回 true
boolean isCancelled() 
//任务是否已经完成。任务正常终止、异常或取消,都将返回true
boolean isDone()
//等待任务执行结束,然后获得V类型的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
V get()
//阻塞时间超过设定的timeout时间,该方法将抛出异常。
V get(long timeout, TimeUnit unit) 

ThreadPoolExecutor中submit()函数返回的为FutureTask

//calss AbstractExecutorService
public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }
public <T> Future<T> submit(Runnable task, T result) 
public <T> Future<T> submit(Callable<T> task)
//newTaskFor方法即为返回对应的FutureTask
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value);}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable);}

FutureTask构造函数接受Callable和Runnable(Runnable会转化为Callable)

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
    }

不使用线程池时,由于FutureTask实现了Runnable接口,因此可以直接通过Thread包装来执行

Callable<Integer> callable = new Callable<Integer>() {
    public Integer call() throws Exception {
        Thread.sleep(1000);
        return new Random().nextInt(100);
    }
};
FutureTask<Integer> future = new FutureTask<Integer>(callable);
new Thread(future).start();

try {
    int result = future.get();
    System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

使用线程池时,可以用executor提交callable任务,然后用Future来接收,也可以用callable来新建FutureTask将其提交submit,之后直接调用该FutureTask的get()方法获取结果。

class CallableDemo implements Callable<Integer> {
    private int sum;
    @Override
    public Integer call() throws Exception {
        System.out.println("start==="+Thread.currentThread().getName());
        for (int i = 0; i < 1000; i++) {
            sum = sum + i;
        }
        System.out.println("end=="+Thread.currentThread().getName());
        return sum;
    }
}
ExecutorService es = Executors.newSingleThreadExecutor();
CallableDemo calTask=new CallableDemo();
Future<Integer> future =es.submit(calTask);
//FutureTask<Integer> futureTask=new FutureTask<>(calTask);
//es.submit(futureTask);
es.shutdown();
try {
    if(future.get()!=null){
        //输出获取到的结果
        System.out.println("future.get()-->"+future.get());
    }else{
        //输出获取到的结果
        System.out.println("future.get()未获取到结果");
    }
} catch (Exception e) {
    e.printStackTrace();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值