Javaのラムダ式でスレッド処理!RunnableとCallableの書き方を徹底解説
生徒
「Javaでスレッドを使いたいんですが、ラムダ式でも書けるって本当ですか?」
先生
「そうだね。ラムダ式を使えば、スレッド処理もすっきり簡潔に書けるようになるよ。特にRunnableやCallableの書き方が変わってくるんだ。」
生徒
「それってどうやって使い分ければいいんですか?」
先生
「それじゃあ、Javaのラムダ式を使ってスレッド処理を書く方法と、Runnable・Callableの違いを一緒に見ていこう!」
1. Runnableとは?Javaでのスレッドの基本
Runnableは、Javaでスレッドを実行するための代表的なインターフェースです。run()メソッドを実装することで、非同期で処理を実行できます。ラムダ式を使えば、コードをすっきり書くことができます。
Thread thread = new Thread(() -> {
System.out.println("スレッドで処理を実行中...");
});
thread.start();
このように、従来は匿名クラスで長々と書いていたコードが、ラムダ式を使うことで数行にまとまります。
2. Callableとは?戻り値が欲しいときのスレッド処理
Callableは、Runnableとよく似ていますが、戻り値を返せるという違いがあります。Runnableでは戻り値がないのに対して、Callableは処理結果を返すことができます。
Callable<String> task = () -> {
return "スレッド完了!";
};
このように、Callableはラムダ式でも記述でき、ExecutorServiceと組み合わせて実行します。
3. ExecutorServiceでスレッドを実行する方法
CallableはThreadで直接実行できないため、ExecutorServiceを使って実行します。実行結果はFutureで受け取ります。
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(() -> {
return "処理が完了しました!";
});
String result = future.get(); // 戻り値を取得
System.out.println(result);
executor.shutdown();
Future.get()は処理が終わるまで待機し、結果を取得します。例外処理を忘れずに入れましょう。
4. RunnableとCallableの違いを比較
RunnableとCallableの違いを簡単に比較してみましょう。
| 項目 | Runnable | Callable |
|---|---|---|
| 戻り値 | なし | あり |
| 例外処理 | チェック例外をスローできない | チェック例外をスローできる |
| 実行方法 | Thread、Executor | Executor経由 |
| 利用シーン | 簡単な並列処理 | 戻り値が必要な処理 |
5. Javaのラムダ式はRunnable・Callableと相性抜群
RunnableやCallableはどちらも「関数型インターフェース」なので、Javaのラムダ式と相性が良いです。関数型インターフェースとは、抽象メソッドが1つだけのインターフェースのことです。
つまり、() -> { 処理 }の形でラムダ式を使うことができ、より簡潔にスレッド処理が書けるようになります。
6. スレッドの非同期処理で活躍するJavaのラムダ式
非同期処理とは、別スレッドで処理を行い、他の処理をブロックせずに並行して動かすテクニックです。GUIアプリやWebアプリでは、レスポンスを保ったまま時間のかかる処理を実行するために使われます。
JavaではThreadやExecutorServiceを使った非同期処理が主流で、ラムダ式を組み合わせることで、コードがシンプルかつ読みやすくなります。
7. 複数スレッドをラムダ式で実行する例
複数のスレッドをラムダ式で同時に実行するには、Executors.newFixedThreadPool()を使うと便利です。
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("タスク" + taskId + "を実行中...");
});
}
executor.shutdown();
このように、複数のスレッドを並列に実行する処理も、ラムダ式で簡単に書くことができます。
8. Javaの並列処理はラムダ式とともに進化した
昔のJavaではスレッド処理を書くのが面倒で、クラスをたくさん定義する必要がありました。しかしJava8以降、ラムダ式によってコードが非常にシンプルになり、可読性も向上しました。
RunnableやCallableをラムダで使うことで、複雑な並列処理も短く書けて、メンテナンスしやすいコードになります。
これからJavaのスレッド処理を学ぶ方は、ぜひラムダ式と一緒に覚えて、実務で使いこなせるようにしましょう。
まとめ
Javaのラムダ式を使ったスレッド処理の全体像を振り返る
この記事では、Javaにおけるスレッド処理をテーマに、ラムダ式を使ったRunnableとCallableの書き方や使い分けについて詳しく解説してきました。 Javaで並列処理や非同期処理を行う場面は、デスクトップアプリケーション、Webアプリケーション、サーバーサイド処理など、実務のあらゆる場所で登場します。 その中で、スレッド処理をいかに分かりやすく、安全に書くかは非常に重要なポイントです。 Java八以降で導入されたラムダ式は、このスレッド処理の記述を大きく進化させ、コード量を減らし、可読性を高めてくれました。
Runnableは、Javaにおける最も基本的なスレッド実行インターフェースで、戻り値を必要としないシンプルな非同期処理に向いています。 ラムダ式を使うことで、runメソッドを明示的に書かずに処理内容だけを記述でき、短く直感的なコードになります。 一方でCallableは、スレッド処理の結果を呼び出し元に返したい場合に使われ、Futureと組み合わせることで処理完了の待機や結果取得が可能になります。 この違いを理解することが、Javaのスレッド処理を正しく使いこなす第一歩です。
ExecutorServiceとラムダ式の重要性
Callableを実行する際に登場したExecutorServiceは、スレッドを直接生成するのではなく、スレッドプールとして管理する仕組みを提供します。 これにより、スレッドの使い回しが可能になり、パフォーマンスやリソース管理の面で大きなメリットがあります。 ラムダ式とExecutorServiceを組み合わせることで、複数スレッドの処理も非常に簡潔に書けるようになりました。 Javaで非同期処理や並列処理を行う場合、この組み合わせはほぼ必須の知識といえます。
また、RunnableとCallableはいずれも関数型インターフェースであるため、ラムダ式と相性が良いという点も重要です。 抽象メソッドが一つだけという特徴があるからこそ、処理内容をそのまま式として渡すことができます。 この考え方に慣れることで、Javaのコード全体がよりモダンで読みやすい構造になっていきます。
ラムダ式を使ったスレッド処理の整理例
ここで、RunnableとCallable、ExecutorServiceを組み合わせた基本的なスレッド処理のイメージを、改めて整理してみましょう。 実務でよく使われる構成を意識したサンプルです。
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
System.out.println("ラムダ式でRunnable処理を実行中");
});
Future<String> future = executor.submit(() -> {
return "Callableの戻り値です";
});
String result = future.get();
System.out.println(result);
executor.shutdown();
このように、Javaのラムダ式を活用することで、スレッド処理の流れが非常に分かりやすくなります。 複雑に見えがちな並列処理も、基本構造を理解すれば、恐れる必要はありません。 重要なのは、RunnableとCallableの役割の違いを理解し、適切な場面で使い分けることです。
生徒
「Javaのスレッド処理って難しい印象がありましたが、ラムダ式を使うとかなり読みやすくなりますね。 RunnableとCallableの違いも、やっと整理できました。」
先生
「それは良い理解ですね。 戻り値が必要かどうかでRunnableとCallableを使い分ける、という考え方が大切です。」
生徒
「ExecutorServiceを使う理由も分かりました。 スレッドを直接作るより、安全で管理しやすいんですね。」
先生
「その通りです。 実務では、スレッドプールとラムダ式を組み合わせた書き方が主流になっています。」
生徒
「これからは、非同期処理を書くときにラムダ式を積極的に使ってみます。」
先生
「ぜひそうしてください。 Javaの並列処理は、ラムダ式を理解することで一気に扱いやすくなりますよ。」