Java多线程--Future与Callable

Callable

Callable与Runnable类似,但是执行任务后能返回结果;Future接口表示异步任务,它能拿到Callable的返回值,即获取结果。
Callable接口如下:

public interface Callable<V> {
    V call() throws Exception;
}

这是一个泛型接口,返回的类型就是传递进来的类型,或者抛出异常。
使用: 一般作为参数,详见后面的例子

Future

Future能具体的Runnable或者Callable任务的执行进行取消、查询是否完成、获取结果。
接口如下:

public interface Future<V> {
    // 取消对此任务的执行
    boolean  cancel(boolean mayInterruptIfRunning);
    // 如果在任务正常完成前将其取消,则返回 true
    boolean  isCancelled(); 
    // 如果任务已完成返回 true
    boolean  isDone(); 
    // 获取执行结果,该方法会阻塞一直等到任务执行完成
    V  get() throws InterruptedException, ExecutionException; 
    // 最多等待为使计算完成所给定的时间之后,获取其结果,如果超时,结果返回null
    V  get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}

Future的实现类:FutureTask

public class FutureTask<V> implements RunnableFuture<V> {
……
public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

可以看到,FutureTask实现了Runnable和Future,既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
FutureTask的两个构造方法:

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
    }

示例如下

使用场景:当前线程(线程A)需要依赖于另一个线程(线程B)的处理结果,而线程B处理结果需要一定的时间,Future模式就可以让线程A的数据请求交给B,需要数据时再去get。而在B处理时A还能处理其他业务。

package com.learn;

import java.util.concurrent.Callable;

public class FooCallable implements Callable<String> {
    private String name;

    public FooCallable(String name) {
        this.name = name;
    }

    @Override
    public String call() throws Exception {
        System.out.println("Task任务执行");
        Thread.sleep(5000);
        return name;
    }

}
package com.learn;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class FutureTaskTest {

    public static void main(String[] args) {
        FooCallable a = new FooCallable("A");
        FutureTask<String> futureTask1 = new FutureTask<>(a);
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(futureTask1);

        System.out.println("主线程执行任务");
        try {
            if (!futureTask1.isDone()) { // 任务没有完成,会等待,直到任务完成
                System.out.println("FutureTask执行结果" + futureTask1.get());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        executorService.shutdown();
        System.out.println("All执行完毕");
    }

}

执行结果:

Task任务执行
主线程执行任务
FutureTask执行结果A
All执行完毕

示例2
采用submit(Callable)

package com.learn;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class FutureTaskTest {

    public static void main(String[] args) {
        FooCallable a = new FooCallable("A");
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> ret = executorService.submit(a);

        System.out.println("主线程执行任务");
        try {
            System.out.println("Task执行结果" + ret.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
        executorService.shutdown();
        System.out.println("All执行完毕");
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值