Java Callable 和 Future 接口示例

Java Callable Future 接口示例

在这个例子中,我们正在创建一个任务,它将返回给定数字的阶乘。

任务完成后的返回值是参数 数字的阶乘。

class FactorialCalculator implements Callable<Integer> 
{
	private final 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.printf("Factorial of %d is :: %d\n", number, result);
		return result;
	}
}

现在当计算器准备好时,我们将使用 ExecutorService 来执行任务。
在这里,我们将创建 10 个任务,这些任务将计算数字 1 到 10 的阶乘。

每个任务都将提交给 ExecutorService 内部管理 2 个线程的线程池。

在检查所有任务的输出之前,我们将使用方法 awaitTermination() 等待所有任务完成。
这是可选步骤,允许我们不等待并在任务完成时开始检查输出。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main 
{
	public static void main(String[] args) throws InterruptedException 
	{
		ExecutorService executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
		List<Future<Integer>> resultList = new ArrayList<>();
		for (int i = 1; i <= 10; i++) {
			FactorialCalculator calculator = new FactorialCalculator(i);
			Future<Integer> result = executor.submit(calculator);
			resultList.add(result);
		}

		executor.awaitTermination(5, TimeUnit.SECONDS);
		for (int i = 0; i < resultList.size(); i++) 
		{
			Future<Integer> result = resultList.get(i);
			Integer number = null;
			try {
				number = result.get();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
			System.out.printf("Main: Task %d: %d\n", i, number);
		}
		executor.shutdown();
	}
}

输出:

Factorial of 1 is :: 1
Factorial of 2 is :: 2
Factorial of 3 is :: 6
Factorial of 4 is :: 24
Factorial of 5 is :: 120
Factorial of 6 is :: 720
Factorial of 7 is :: 5040
Factorial of 8 is :: 40320
Factorial of 9 is :: 362880
Factorial of 10 is :: 3628800
Main: Task 0: 1
Main: Task 1: 2
Main: Task 2: 6
Main: Task 3: 24
Main: Task 4: 120
Main: Task 5: 720
Main: Task 6: 5040
Main: Task 7: 40320
Main: Task 8: 362880
Main: Task 9: 3628800

在上面的例子中,当我们使用 submit()方法发送要在执行器中执行的可调用对象时,它返回一个 Future对象,你可以使用它有两个主要目标:

https://onitroad.com 更多教程

Future 接口

Future 接口具有获取“Callable”对象生成的结果并管理其状态的方法。

它表示异步计算的结果。

结果只能在计算完成后使用 get() 方法检索,必要时阻塞直到它准备好。

任务的取消由 cancel()方法执行。
一旦计算完成,就不能取消计算。

public interface Future<V> 
{
	boolean cancel(boolean mayInterruptIfRunning);
	boolean isCancelled();
	boolean isDone();
	V get() throws InterruptedException, ExecutionException;
	V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

Callable 接口

在 Java 并发中,Callable 表示返回结果的任务。

Executor 可以同时运行可调用的任务。

从 Java 8 开始,它是一个函数式接口,因此可以用作 lambda 表达式或者方法引用的赋值目标。

@FunctionalInterface
public interface Callable<V> {
/**
 * Computes a result, or throws an exception if unable to do so.
 *
 * @return computed result
 * @throws Exception if unable to compute a result
 */
V call() throws Exception;
}
日期:2020-09-17 00:09:33 来源:oir作者:oir