多线程(25)Callable接口

260 阅读2分钟

Callable接口是Java并发包(java.util.concurrent)中的一部分,自Java 5开始引入。它代表了一个异步计算任务,这个任务可以调用并返回结果。Callable接口类似于Runnable,但它可以返回结果并且能够抛出检查异常。Callable通常与ExecutorService配合使用,提交给线程池执行,并返回一个Future对象来获取计算结果。

Callable接口的定义

Callable接口定义非常简单,如下所示:

public interface Callable<V> {
    V call() throws Exception;
}

这里的VCallable任务执行后返回的结果类型。call()方法是执行任务的地方,它可以返回结果或抛出异常。

如何使用Callable

实现Callable接口需要实现call()方法。下面是一个简单的示例:

Callable<Integer> task = new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        int result = 0;
        // 模拟计算
        for (int i = 0; i < 100; i++) {
            result += i;
        }
        return result; // 返回计算结果
    }
};

或者使用Java 8的lambda表达式简化:

Callable<Integer> task = () -> {
    int result = 0;
    for (int i = 0; i < 100; i++) {
        result += i;
    }
    return result;
};

提交Callable任务给ExecutorService执行,并通过返回的Future对象来获取结果:

ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> future = executor.submit(task);

try {
    // 等待任务执行完成,并获取其结果
    Integer result = future.get();
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

executor.shutdown();

Callable与Runnable的比较

  • 返回值Runnable接口的run()方法不返回任何值,而Callablecall()方法可以返回一个结果。
  • 异常Runnablerun()方法不能抛出检查异常,只能内部处理或抛出非检查异常;Callablecall()方法可以抛出异常,异常可通过Future.get()方法传递给调用者。
  • 用途Runnable适用于不需要返回结果或处理异常的并发任务;Callable适用于可能需要返回结果和处理异常的复杂并发任务。

使用场景

Callable接口适合处理需要返回结果的并发任务。例如,可能需要从多个并发任务中收集结果,然后汇总这些结果。Callable任务在各种场景下都非常有用,特别是那些计算密集型的任务,或者那些需要在任务完成时返回一个值的任务。通过与ExecutorServiceFuture结合使用,Callable提供了一种强大而灵活的并发编程模型。