FutureTask与AQS不得不说的故事

本文详细解析了Runnable、Callable、Future、FutureTask之间的关系,以及FutureTask如何利用AQS(AbstractQueuedSynchronizer)实现任务的执行状态管理。通过分析FutureTask的get()和run()方法,阐述了任务执行过程中的状态变迁,以及如何通过Future获取任务结果。文章还介绍了ExecutorService的submit()方法如何将Callable任务转换为FutureTask并提交到线程池执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    讲FutureTask之前,先讲讲Runnable,Callable,Future,FutureTask之间都是啥关系?
    在接触Callable之前,我们都说,开线程执行一个方法是获取不到返回值的。为什么这么说呢?
    首先是Runnable接口,我们一般实现该接口后都会重写run()方法,这里可以看到run()方法是没有返回值的。也就是说,如果你在run()方法里面,做了一次数据库查询操作,获取到的结果是无法通过方法返回的。只能通过别的方式来获取,比如你可以赋值给一个静态变量或者全局变量,会特别麻烦。
    

public abstract void run();

    
    而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;
}

    常见的用法:

 private ExecutorService exe=Executors.newFixedThreadPool(2);
private void CallableTest(){
          Callable<Integer> c=new Callable<Integer>() {

              @Override
              public Integer call() throws Exception {
                   //假设这里花费了2S做了复杂的计算操作
                   Thread.sleep(2*1000);
                   return 222;
              }
          };

          Future<Integer> f=exe.submit(c);
          //这中间可以做一些别的操作
          try {
              Integer result =f.get();//在需要的时候再来获取执行的结果
              System.out.println(result);
          } catch (InterruptedException e) {
              e.printStackTrace();
          } catch (ExecutionException e) {
              e.printStackTrace();
          }
     }

    
    通常是实现Callable接口的call()方法,然后在里面写你的逻辑。创建好之后,把它提交到线程池中,它就会执行。然后在你需要获取结果的时候,调用future.get()方法获取执行的结果。因为Callable是可以获取返回值的,所以我们可以把一些耗时的任务放在前面执行,然后在后面需要的结果的时候再来获取。

    那Future又是啥呢?可以看到,我们前面是通过Future.get()来获取Callable返回的结果,还可以通过Future.isDone()来判断任务是否已经执行完了,以及取消这个任务,限时获取任务的结果等。而如果任务没有执行完,future.get()会阻塞调用的线程直到任务执行完后返回结果。

    FutureTask则是实现Future这么多功能的核心。
    FutureTask实现了RunnableFuture接口,RunnableFuture接口则是继承了Runnable,Future接口类。FutureTask类用于包装Callable和Runnable,然后提交给线程池执行。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值