FutureTask 原理剖析

本文介绍了FutureTask在多线程并发编程中的作用,详细阐述了FutureTask.get()方法的阻塞和唤醒原理,以及FutureTask的生命周期和不同状态下的行为。同时,分析了FutureTask的内部实现,包括waiters链表和线程唤醒的顺序,讨论了可能的公平性问题。
摘要由CSDN通过智能技术生成

戳蓝字「TopCoder」关注我们哦!

编者注:FutureTask用于在异步操作场景中,FutureTask作为生产者(执行FutureTask的线程)和消费者(获取FutureTask结果的线程)的桥梁,如果生产者先生产出了数据,那么消费者get时能会直接拿到结果;如果生产者还未产生数据,那么get时会一直阻塞或者超时阻塞,一直到生产者产生数据唤醒阻塞的消费者为止。话不多说,下来开始FutureTask的分析~

Future接口和实现Future接口的FutureTask,代表异步计算的结果,Future使用示例如下:

ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10,
        60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

Future future = executor.submit(() -> {
    System.out.println("hello world");
    return "hello world";
});
System.out.println(future.get());

Future接口声明如下:

FutureTask除了实现Future接口外,还实现了Runnable接口。因此,FutureTask可以交给Executor执行,也可以由调用线程直接执行(FutureTask.run())。根据FutureTask.run()方法被执行的时机,FutureTask可以处于以下3种状态:未启动、运行中、已完成

当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞;当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常。

  • 当FutureTask处于未启动状态时,执行FutureTask.cancel()方法将导致此任务永远不会被执行;

  • 当FutureTask处于已启动状态时,执行FutureTask.cancel(true)方法将以中断执行此任务线程的方式来试图停止任务;

  • 当FutureTask处于已启动状态时,执行FutureTask.cancel(false)方法将不会对正在执行此任务的线程产生影响(让正在执行的任务运行完成);

  • 当FutureTask处于已完成状态时,执行FutureTask.cancel(…)方法将返回false。

FutureTask的生命周期如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值