ExecutorService、Callable、Future实现有返回结果的多线程原理解析

在并发多线程场景下,存在需要获取各线程的异步执行结果,这时,就可以通过ExecutorService线程池结合Callable、Future来实现。

我们先来写一个简单的例子——

public class ExecutorTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Callable callable = new MyCallable();
        Future future = executor.submit(callable);
        System.out.println("打印线程池返回值:" + future.get());
    }
}

class MyCallable implements Callable<String>{
    @Override
    public String call() throws Exception {
        return "测试返回值";
    }
}

执行完成后,会打印出以下结果:

打印线程池返回值:测试返回值

可见,线程池执行完异步线程任务,我们是可以获取到异步线程里的返回值。

那么,ExecutorService、Callable、Future实现有返回结果的多线程是如何实现的呢?

首先,我们需要创建一个实现函数式接口Callable的类,该Callable接口只定义了一个被泛型修饰的call方法,这意味着,需要返回什么类型的值可以由具体实现类来定义——

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

因此,我自定义了一个实现Callable接口的类,该类的重写了call方法,我们在执行多线程时希望返回什么样的结果,就可以在该重写的call方法定义。

class MyCallable implements Callable<String>{
    @Override
    public String call() throws Exception {
        return "测试返回值";
    }
}

在自定义的MyCallable类中,我在call方法里设置一个很简单的String返回值 “测试返回值”,这意味着,我是希望在线程池执行完异步线程任务时,可以返回“测试返回值”这个字符串给我。

接下来,我们就可以创建该MyCallable类的对象,然后通过executor.submit(callable)丢到线程池里,线程池里会利用空闲线程来帮我们执行一个异步线程任务。

ExecutorService executor = Executors.newSingleThreadExecutor();
Callable callable = new MyCallable();
Future future = executor.submit(callable);

值得注意一点是,若需要实现获取线程返回值的效果&#x

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CallableFutureJava 多线程编程中的两个重要概念。 Callable 接口定义了一个 call() 方法,可以用来返回一个结果并可能抛出异常。与 Runnable 接口不同,Callable 接口的任务执行后可以返回一个值,该值可以通过 Future 接口来获取。 Future 接口用于表示异步计算的结果。它提供了一些方法,可以用来检查计算是否完成、等待计算完成并获取结果等。通过 Future 接口,我们可以在一个线程中启动一个计算任务,并在另一个线程中等待计算的结果。 举个例子,我们可以通过创建一个 Callable 对象来实现一个计算任务,然后将该对象提交给一个 ExecutorService,线程池会在后台启动一个线程来执行该任务ExecutorService.submit() 方法会返回一个 Future 对象,我们可以通过该对象来获取计算结果。 下面是一个简单的例子: ```java import java.util.concurrent.*; public class Test { public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<Integer> task = () -> { TimeUnit.SECONDS.sleep(1); return 123; }; ExecutorService executor = Executors.newFixedThreadPool(1); Future<Integer> future = executor.submit(task); System.out.println("future done? " + future.isDone()); Integer result = future.get(); System.out.println("future done? " + future.isDone()); System.out.print("result: " + result); executor.shutdown(); } } ``` 输出结果: ``` future done? false future done? true result: 123 ``` 在这个例子中,我们创建了一个 Callable 对象 task,它会在后台睡眠一秒钟后返回 123。然后我们将该对象提交给一个 ExecutorService,线程池会在后台启动一个线程来执行该任务ExecutorService.submit() 方法会返回一个 Future 对象 future,我们可以通过该对象来获取计算结果。 在主线程中,我们首先检查 future 是否已经完成,然后调用 future.get() 方法来等待计算的结果。由于计算任务需要睡眠一秒钟,因此主线程会在这里等待一秒钟。当计算完成后,future.get() 方法会返回计算结果。最后我们再次检查 future 是否已经完成,并输出计算结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值