Java中带返回值的线程池Future

如何获取任务执行结果

Java通过ThreadPoolExecutor提供的三个submit()方法和一个FutureTask工具类来支持获得任务执行结果的需求。


// 提交Runnable任务
Future<?> 
  submit(Runnable task);
// 提交Callable任务
<T> Future<T> 
  submit(Callable<T> task);
// 提交Runnable任务及结果引用  
<T> Future<T> 
  submit(Runnable task, T result);

Future接口有下面5个方法,其中最后一个get(timeout,unit)支持超时机制。通过Future接口的5个方法,你会发现,我们提交的任务不但能够获取任务执行结果,还可以取消任务。不过值得注意的是:这两个get方法都是阻塞式的,如果被调用的时候,任务还没有执行完,那么调用get方法的线程会阻塞,指导任务执行完才会被唤醒。


// 取消任务
boolean cancel(
  boolean mayInterruptIfRunning);
// 判断任务是否已取消  
boolean isCancelled();
// 判断任务是否已结束
boolean isDone();
// 获得任务执行结果
get();
// 获得任务执行结果,支持超时
get(long timeout, TimeUnit unit);

这3个submit方法之间的区别在于方法参数不同:

  1. 提交Runnbale任务submit(Runnable task):这个方法参数Runnable的run方法是没有返回值的,所以这个方法返回的Future仅可以用来断言任务已经结束,类似于Thread.join();
  2. 提交Callable任务submit(Callable<T> task):这个方法的参数是一个Callable接口,只有一个call方法,并且这个方法是有返回值的,可以通过get方法来获取任务执行结果。
  3. 提交Runnable任务及结果引用submit(Runnable task, T result):假设这个方法返回Future对象时f,f.get的返回值就是传给submit方法的参数result,result相当于主线程和子线程之间的桥梁,通过它主子线程可以共享数据。
public class FutureDemo {
    static class Result{
        private String resultStr;

        public String getResultStr() {
            return resultStr;
        }

        public void setResultStr(String resultStr) {
            this.resultStr = resultStr;
        }
    }
    static class Task implements Runnable{
        Result r;

        public Task(Result r) {
            this.r = r;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + ":" + r.getResultStr());
            r.setResultStr("hello Java");
            System.out.println(Thread.currentThread().getName() + ":" + r.getResultStr());
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        Result result = new Result();
        result.setResultStr("hello world");
        Future<Result> future = executor.submit(new Task(result), result);
        System.out.println(Thread.currentThread().getName() + ":" + result.getResultStr()); // hello world
        System.out.println(Thread.currentThread().getName() + ":" + future.get().getResultStr()); // hello Java
    }
}
FutureTask工具类

FutureTask(Callable<V> callable);
FutureTask(Runnable runnable, V result);

// 创建FutureTask
FutureTask<Integer> futureTask
  = new FutureTask<>(()-> 1+2);
// 创建线程池
ExecutorService es = 
  Executors.newCachedThreadPool();
// 提交FutureTask 
es.submit(futureTask);
// 获取计算结果
Integer result = futureTask.get();

// 创建FutureTask
FutureTask<Integer> futureTask
  = new FutureTask<>(()-> 1+2);
// 创建并启动线程
Thread T1 = new Thread(futureTask);
T1.start();
// 获取计算结果
Integer result = futureTask.get();

实现最优的"烧水泡茶"程序

在这里插入图片描述

 public static void main(String[] args) {
        FutureTask<String> task2 = new FutureTask<>(()->{
            System.out.println("洗茶壶");
            System.out.println("洗茶杯");
            System.out.println("拿茶叶");
            return "茶叶AAA";
        });
        FutureTask task1 = new FutureTask(new FutureTask2(task2));
        Thread t1 = new Thread(task1);
        Thread t2 = new Thread(task2);
        t1.start();
        t2.start();
    }
    static class FutureTask2 implements Callable<String>{

        FutureTask<String> f1;

        public FutureTask2(FutureTask<String> f1) {
            this.f1 = f1;
        }

        @Override
        public String call() throws Exception {
            System.out.println("洗水壶");
            System.out.println("烧开水");
            System.out.println("泡茶"+f1.get());
            return "";
        }
    }
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值