概要
処理結果を戻したり必要に応じて例外をスローするマルチスレッドのタスクを定義するためのインタフェースである。
Callable
インタフェースは以下のように定義されている。
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Callable
インタフェースはV
というジェネリック型を持つcall()
メソッドのみ定義されている。
戻り値型はCallable
のインスタンスを取得する際に指定する型パラメータとなる。
例①:処理結果を取得
import java.util.concurrent.*;
public class CallableExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> {
TimeUnit.SECONDS.sleep(2);
return 42;
};
Future<Integer> future = executorService.submit(task);
System.out.println("Task submitted, waiting for the result...");
// タスクの実行結果を取得
Integer result = future.get();
System.out.println("Task completed, result: " + result);
executorService.shutdown();
}
}
上記の例では、Callable<Integer>
を実装して非同期タスクを定義している。
タスクは2秒間スリープし、整数値42を返す。
submit()
メソッドを使用してタスクを非同期に実行し、Future<Integer>
オブジェクトを取得している。Future<Integer>
はタスクの実行結果を表し、get()
メソッドを使用して結果を取得する。
上記の例では、future.get()
によりタスクの結果を取得し、結果を表示している。result
変数には整数値42が格納される。
例②:例外を受け取る
import java.util.concurrent.*;
public class ExceptionHandlingExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> {
TimeUnit.SECONDS.sleep(2);
throw new RuntimeException("Oops! Something went wrong.");
};
Future<Integer> future = executorService.submit(task);
System.out.println("Task submitted, waiting for the result...");
try {
Integer result = future.get();
System.out.println("Task completed, result: " + result);
} catch (ExecutionException e) {
Throwable cause = e.getCause();
System.out.println("Task failed with exception: " + cause.getMessage());
}
executorService.shutdown();
}
}
上記の例では、Callable
を使用して非同期タスクを定義し、タスクは2秒間スリープした後にRuntimeException
をスローする。
ExecutorService
のsubmit()
メソッドを使用してタスクを非同期に実行し、Future
オブジェクトを取得する。
future.get()
を呼び出してタスクの結果を取得している。このメソッドはタスクが例外をスローした場合にはExecutionException
が発生する。
スレッド内で発生した例外はExecutionException
の内部に保持されている。そのため、try-catch
ブロックを使用してExecutionException
をキャッチし、その中のgetCause()
メソッドを使用して原因となった例外を取得することができる。
実行結果
Task submitted, waiting for the result...
Task failed with exception: Oops! Something went wrong.
この例では、ExecutionException
をキャッチし、原因となった例外を取得して適切なエラーメッセージを表示することで、例外を処理している。