Java Callable Future Example
Java 并发执行框架的优势之一是支持运行并发任务,并在任务处理后返回单个结果。Java 并发 API 通过 Callable 和 Future 两个接口实现了这一功能。
1. Java Callable 和 Future 接口
1.1 Callable 接口
Callable 接口定义了 call() 方法,我们需要在该方法中实现具体的任务逻辑。Callable 是一个泛型接口,这意味着我们必须指定 call() 方法将返回的数据类型。
1.2 Future 接口
Future 接口提供了获取 Callable 任务生成结果以及管理任务状态的方法。
2. Java Callable 与 Future 示例
在本示例中,我们创建了一个实现 Callable 接口的 FactorialCalculator 类。这意味着我们将重写其 call() 方法,并在计算完成后从该方法返回结果。随后,主程序可以通过保存的 Future 引用检索此结果。
// FactorialCalculator.java
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class FactorialCalculator implements Callable<Integer> {
private Integer number;
public FactorialCalculator(Integer number) {
this.number = number;
}
@Override
public Integer call() throws Exception {
int result = 1;
if ((number == 0) || (number == 1)) {
result = 1;
} else {
for (int i = 2; i <= number; i++) {
result *= i;
TimeUnit.MILLISECONDS.sleep(20);
}
}
System.out.println("Result for number - " + number + " -> " + result);
return result;
}
}现在,让我们使用两个线程和 4 个数字来测试上面的阶乘计算器。
// CallableExample.java
package com.howtodoinjava.demo.multithreading;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CallableExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
List<Future<Integer>> resultList = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 4; i++) {
Integer number = random.nextInt(10);
FactorialCalculator calculator = new FactorialCalculator(number);
Future<Integer> result = executor.submit(calculator);
resultList.add(result);
}
for (Future<Integer> future : resultList) {
try {
System.out.println("Future result is - " + " - " + future.get() + "; And Task done is " + future.isDone());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// shut down the executor service now
executor.shutdown();
}
}程序输出示例:
Result for number - 4 -> 24
Result for number - 6 -> 720
Future result is - - 720; And Task done is true
Future result is - - 24; And Task done is true
Result for number - 2 -> 2
Result for number - 6 -> 720
Future result is - - 720; And Task done is true
Future result is - - 2; And Task done is true在此示例中,我们使用 submit() 方法将 Callable 对象提交给执行器(Executor)执行。该方法接收一个 Callable 对象作为参数,并返回一个 Future 对象。Future 对象主要用于以下两个目的:
- 控制任务状态:我们可以取消任务或检查任务是否完成。为此,我们使用
isDone()方法来检查任务状态。 - 获取返回结果:我们可以通过
call()方法获得返回的结果。为此,我们使用get()方法。该方法会阻塞直到Callable对象完成call()方法的执行并返回结果。
如果线程在 get() 方法等待结果时被中断,它将抛出 InterruptedException 异常。如果 call() 方法执行过程中抛出异常,则 get() 方法会抛出 ExecutionException 异常。
Future 接口还提供了另一个 get() 方法的重载版本:get(long timeout, TimeUnit unit)。如果在指定时间内结果仍不可用,该方法将抛出 TimeoutException 异常,而不是无限期等待。
参考:http://images.jsdiff.com/archives/15507075
说明:本文示例基于 Java 5 及以上版本,Callable与Future核心接口行为在后续版本中保持稳定。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/java-callable-future-example.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。