和阿里面试官对线FutureTask源码面试(上)

简介: 和阿里面试官对线FutureTask源码面试(上)

1 简介

  • 使用继承方式的好处是方便传参,可在子类里面添加成员变量,通过 set 方法设置参数者通过构造器进行传递
  • 使用 Runnable 方式,则只能使用主线程里面被声明为 final 变量

不好的地方是 Java 不支持多继承,若继承了 Thread 类,则子类不能再继承其它类 ,而 Runable接口则无该限制 。

Thread 类和 Runnable 接口都不允许声明检查型异常,也不能定义返回值。


没有返回值就有点麻烦,这两种方式都没办法拿到任务的返回结果,但FutureTask 可以!


不能声明抛出检查型异常则更麻烦一些。run()方法意味着必须捕获并处理检查型异常。即使小心地保存了异常信息(在捕获异常时)以便稍后检查,但也不能保证这个 Runnable 对象的所有使用者都读取异常信息。

可以修改Runnable实现的getter,让它们都能抛出任务执行中的异常。但这种方法除了繁琐也不是十分安全可靠,你不能强迫使用者调用这些方法,程序员很可能会调用join()方法等待线程结束然后就不管了。


但是现在不用担心了,以上的问题终于在1.5中解决了。

Callable接口和Future接口的引入以及他们对线程池的支持优雅地解决了这两个问题。

2 案例

FutureTask 相关组件如何使用的=

image.png

3 Callable

Callable函数式接口定义了唯一方法 - call()。可以在Callable的实现中声明强类型的返回值,甚至抛异常。

利用call()直接返回结果,省去读取值时的类型转换。

  • 定义
  • image.png
  • 返回值是个泛型,使用时,不会直接使用 Callable,而是和 FutureTask 协同。

4 Future

  • Callable 可以返回线程的执行结果,在获取结果时,就需用到Future接口
  • image.png
  • Future是 Java5 中引入的接口,当提交一个Callable对象给线程池时,将得到一个Future对象,并且它和传入的Callable有相同的结果类型声明。


它取代了Java5 前直接操作 Thread 实例做法。以前,不得不用Thread.join()或Thread.join(long millis)等待任务完成。


Future表示异步计算的结果,提供了一些方法来检查计算是否完成,等待其完成以及检索计算结果。

只有在计算完成时才可以使用get方法检索结果,必要时将其阻塞,直到准备就绪。

取消是通过cancel方法执行的。

提供了其他方法来确定任务是正常完成还是被取消。一旦计算完成,就不能取消计算。


如果出于可取消性的目的使用Future而不提供可用的结果,则可以声明Future <?>形式的类型,并作为基础任务的结果返回null。

4.1 Future API

4.1.1 cancel - 尝试取消执行任务

image.png

当任务处于不同状态时,该方法有不同响应:


任务已完成 / 已取消 / 由于某些其他原因无法被取消

该尝试会直接失败

尝试成功,且此时任务尚未开始

可以取消成功

任务已开始

mayInterruptIfRunning 参数确定是否可以中断执行该任务的线程以尝试停止该任务。

此方法返回后,对 isDone 的后续调用将始终返回 true。若此方法返回 true,则随后对 isCancelled 的调用将始终返回 true。

4.1.2 isCancelled - 是否被取消

image.png

如果此任务在正常完成之前被取消,则返回true.

4.1.3 isDone - 是否完成

image.png

如果此任务完成,则返回true。

完成可能是由于正常终止,异常或取消引起的,在所有这些情况下,此方法都将返回true。

4.1.4 get - 获取结果

等待任务完成,然后获取其结果。

image.png

若:

  • 任务被取消,抛 CancellationException
  • 当前线程在等待时被中断,抛 InterruptedException
  • 任务抛出了异常,抛 ExecutionException
目录
相关文章
|
5月前
|
监控 Java 数据安全/隐私保护
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
阿里面试:SpringBoot启动时, 如何执行扩展代码?你们项目 SpringBoot 进行过 哪些 扩展?
|
4月前
|
负载均衡 架构师 Cloud Native
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选 CP 还是 AP?为什么?
阿里面试:服务与发现 ,该选  CP 还是 AP?为什么?
|
5月前
|
SQL Java 数据库连接
阿里腾讯互联网公司校招 Java 面试题总结及答案解析
本文总结了阿里巴巴和腾讯等互联网大厂的Java校招面试题及答案,涵盖Java基础、多线程、集合框架、数据库、Spring与MyBatis框架等内容。从数据类型、面向对象特性到异常处理,从线程安全到SQL优化,再到IOC原理与MyBatis结果封装,全面梳理常见考点。通过详细解析,帮助求职者系统掌握Java核心知识,为校招做好充分准备。资源链接:[点击下载](https://pan.quark.cn/s/14fcf913bae6)。
186 2
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
310 4
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
1966 2