java 多线程系列文章列表, 请查看目录: 《java 多线程学习笔记》
1. Callable 方式
Callable 方式最主要的特点就是可以阻塞式获取子线程执行结果, 也就是说对于长耗时的任务,可以放到子线程中执行, 而主线程去执行其它任务. 当主线程执行完其它任务之后, 需要获取子线程任务返回结果时, 如果子线程没有执行完, 主线程会阻塞, 等子线程执行完之后, 再继续执行.
1.1 Callable 特点
- 面向接口编程, 松耦合设计
- 在多线程模式下,可实现对象资源共享. 但是需要注意使用原子类变量AtomicXXX
- 不能独立运行, 需绑定在Thread实例上运行
- 有返回值, 主线程可等待异步线程执行结果, 可捕获异步线程异常
1.2 使用步骤
- 自定义Callable 子类, 并创建子类实例. 可使用普通类, 匿名内部类, lambda 表达式等方式
- 创建异步任务, Future 接口实例
- 创建线程, 绑定Future任务, 并启动异步线程
- 阻塞获取异步线程结果
1.3 适用场景
- 主线程需要等待异步任务执行结束时
- 主线程获取异步任务执行结果时
- 主线程需要捕获异步线程异常时
- 主线程需要
1.4 Future API
方法签名 | 方法描述 | 参数 |
---|---|---|
boolean cancel(boolean mayInterruptIfRunning) | 取消异步任务. | 如过正在运行, 是否强制取消 |
boolean isCancelled() | 子线程是否被取消 | 无 |
boolean isDone() | 子线程是否结束, 子线程被取消也会返回true | 无 |
V get() | 获取异步线程返回结果, 如果线程被取消或执行过程抛出异常, 则会抛出异常 | 无 |
V get(long timeout, TimeUnit unit) | 获取异步线程返回结果, 指定阻塞时间, 超时抛出异常 | 阻塞等待时间 |
2. 场景示例
2.1 主线程等待异步线程结束
- 异步线程执行长耗时任务时, 主线程不阻塞, 继续执行任务
- 主线程获取异步线程执行结果时, 如果异步线程未结束或进行阻塞
- 异步线程执行过程抛出异常时, 主线程可在获取异步线程执行结果时捕获
public static void main(String[] args){
// 1. 创建Callable 实例
Callable callable =new Callable<String>(){
public String call() throws Exception {
String time = Thread.currentThread().getName() + "-" + LocalDateTime.now().toString();
Thread.sleep