并发工具类:ExecutorService、Future、CountDownLatch与Semaphore(第二章)

目录

一、Future

概念解析

方法详解

cancel()方法

Future与ExecutorService配合使用


一、Future

概念解析

Future是Java并发包(java.util.concurrent)中的一个重要接口,它代表异步计算的结果。在异步计算模型中,Future作为异步任务结果的占位符和查询器,提供了以下功能:

  1. 占位符:当一个异步任务(通常是通过ExecutorService提交的RunnableCallable任务)开始执行后,会返回一个与该任务关联的Future对象。这个Future对象如同一个“承诺”,表示未来某个时刻将产生一个计算结果。

  2. 查询器:通过Future对象,可以查询异步任务的执行状态(如是否已完成、是否已取消),并最终获取计算结果。Future接口提供了相应的方法,如isDone()isCancelled()get(),供客户端代码监视任务进展并访问结果。

方法详解

get()方法

get()方法是Future接口的核心方法,用于获取异步任务的计算结果。根据是否指定超时时间,get()方法有两种模式:

同步获取结果:调用无参的get()方法时,如果任务尚未完成,当前线程将阻塞等待任务完成。一旦任务完成,方法返回计算结果。如果任务抛出异常,get()方法将该异常封装为ExecutionException抛出。

示例代码:

Future<Integer> future = executor.submit(() -> {
    // 执行耗时任务并返回结果
    return someComputation();
});

try {
    Integer result = future.get();  // 阻塞等待任务完成,返回结果
    System.out.println("Result: " + result);
} catch (InterruptedException e) {
    // 当前线程被中断,通常需要重新设置中断状态并处理中断逻辑
    Thread.currentThread().interrupt();
    // ...
} catch (ExecutionException e) {
    // 处理任务执行期间抛出的异常
    Throwable cause = e.getCause();
    System.out.println("Task failed with exception: " + cause.getMessage());
}

超时获取结果:调用带超时参数的get(long timeout, TimeUnit unit)方法时,如果任务在指定时间内完成,方法返回计算结果。若超时后任务仍未完成,方法将抛出TimeoutException。若任务在等待期间抛出异常,get()方法将该异常封装为ExecutionException抛出。

示例代码:

Future<Integer> future = executor.submit(() -> {
    // 执行耗时任务并返回结果
    return someComputation();
});

try {
    Integer result = future.get(5, TimeUnit.SECONDS);  // 最多等待5秒,然后返回结果或抛出异常
    System.out.println("Result: " + result);
} catch (InterruptedException e) {
    // 当前线程被中断,通常需要重新设置中断状态并处理中断逻辑
    Thread.currentThread().interrupt();
    // ...
} catch (ExecutionException e) {
    // 处理任务执行期间抛出的异常
    Throwable cause = e.getCause();
    System.out.println("Task failed with exception: " + cause.getMessage());
} catch (TimeoutException e) {
    System.out.println("Task timed out");
}

cancel()方法

cancel()方法用于尝试取消关联的异步任务。根据参数mayInterruptIfRunning的不同值,取消分为两种模式:

  1. 正常取消:当mayInterruptIfRunningfalse时,如果任务尚未开始执行或已经完成,任务将被取消。如果任务正在执行,取消操作将不会中断任务,仅标记任务为已取消。后续调用isCancelled()将返回true,但任务仍会继续执行至完成。

  2. 强中断:当mayInterruptIfRunningtrue时,除了上述正常取消的行为外,如果任务正在执行,系统将试图中断执行任务的线程。这通常通过调用线程的interrupt()方法实现。被中断的任务可以选择响应中断,提前结束执行。

    示例代码:

Future<Integer> future = executor.submit(() -> {
    // 执行耗时任务并返回结果
    return someComputation();
});

// 尝试取消任务,允许中断正在运行的任务
boolean cancelled = future.cancel(true);

if (cancelled) {
    System.out.println("Task was cancelled");
} else {
    System.out.println("Task could not be cancelled");
}

Future与ExecutorService配合使用

下面的示例展示了如何使用Future对象与ExecutorService结合,实现对异步任务的提交、取消、结果获取等操作:

ExecutorService executor = Executors.newFixedThreadPool(5);

// 提交一个异步任务
Future<Integer> future = executor.submit(() -> {
    // 执行耗时任务并返回结果
    return someComputation();
});

// 在主线程中进行其他操作...

// 查询任务是否已完成
if (future.isDone()) {
    System.out.println("Task has completed");
}

// 尝试取消任务,允许中断正在运行的任务
boolean cancelled = future.cancel(true);

if (cancelled) {
    System.out.println("Task was cancelled");
} else {
    System.out.println("Task could not be cancelled");
}

try {
    // 超时5秒后获取结果,若超时则抛出TimeoutException
    Integer result = future.get(5, TimeUnit.SECONDS);
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    // 处理异常
    System.out.println("Failed to retrieve task result: " + e.getMessage());
}

// 关闭ExecutorService
executor.shutdown();

通过这样的方式,开发者可以利用Future接口有效地管理异步任务,监控任务状态,及时获取计算结果,甚至在必要时取消任务,实现对异步计算流程的灵活控制。

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值