HOWTO · Java

Java 中的 Runnable 与 Callable 接口

本文介绍 Java 中 Runnable 和 Callable 接口的区别。

本教程通过 Java 中的示例介绍了 RunnableCallable 接口之间的区别。

Java 中的 Runnable 接口

Runnable 是用于在 Java 中创建和运行线程的接口。它只有一个抽象方法 run(),也称为 Functional 接口。

你可以在下面看到 Runnable 接口的签名及其 SAM 方法。

@FunctionalInterface public interface Runnable
void run() // Single Abstract Method

Java 中的 Runnable 接口示例

每个想要创建和运行线程的类都必须实现 Runnable 接口或扩展 Thread 类。

Runnable 接口提供了一个 run() 方法,该方法必须在基类中被覆盖。该方法由 start() 方法隐式执行。请参见下面的示例。

public class SimpleTesting implements Runnable {
  public static void main(String[] args) {
    new Thread(new SimpleTesting()).start();
  }
  @Override
  public void run() {
    System.out.println("Running a thread");
  }
}

输出:

Running a thread

Java 中的 Callable 接口

Callable 是一个接口,类似于 Runnable 接口。它还包含一个抽象方法,call()

这个接口是为那些实例可能被另一个线程执行的类设计的。Callable 接口和方法的签名如下:

Executors 类包含从其他常见形式转换为 Callable 类的实用方法。

@FunctionalInterface public interface Callable<V>
V call() throws Exception

Java 中的 Callable 接口示例

我们实现了 Callable 接口并覆盖了它的 call() 方法。我们可以为 call() 方法获取任何对象。

请参见下面的示例。

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;

public class SimpleTesting implements Callable<Integer> {
  public static void main(String[] args) throws InterruptedException, ExecutionException {
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    SimpleTesting st = new SimpleTesting();
    Future<Integer> future = executorService.submit(st);
    int result = future.get().intValue();
    System.out.println("product " + result);
  }

  @Override
  public Integer call() throws Exception {
    int product = 23 * 12;
    return product;
  }
}

输出:

product 276

Java 中的 Runnable VS Callable 接口

下表包含一些理解 Java 的 RunnableCallable 接口的要点。

Runnable Callable
实现类必须相应地重写它的 run() 方法。 实现类必须相应地覆盖其 call() 方法。
run() 方法的返回类型是 void,因此不会向调用者返回任何内容。 call() 方法的返回类型是一个对象。它可以是字符串、整数等。
run() 方法不会抛出任何异常。 call() 方法可以在执行期间抛出异常。
它可用于在 Java 中创建线程。 它不能用于创建线程。