カテゴリ: Java 更新日: 2025/12/15

Javaのラムダ式でスレッド処理!RunnableとCallableの書き方を徹底解説

【ラムダ式】スレッドで使う:Runnable/Callableの書き方(thread対応)
【ラムダ式】スレッドで使う:Runnable/Callableの書き方(thread対応)

先生と生徒の会話形式で理解しよう

生徒

「Javaでスレッドを使いたいんですが、ラムダ式でも書けるって本当ですか?」

先生

「そうだね。ラムダ式を使えば、スレッド処理もすっきり簡潔に書けるようになるよ。特にRunnableCallableの書き方が変わってくるんだ。」

生徒

「それってどうやって使い分ければいいんですか?」

先生

「それじゃあ、Javaのラムダ式を使ってスレッド処理を書く方法と、RunnableCallableの違いを一緒に見ていこう!」

1. Runnableとは?Javaでのスレッドの基本

1. Runnableとは?Javaでのスレッドの基本
1. Runnableとは?Javaでのスレッドの基本

Runnableは、Javaでスレッドを実行するための代表的なインターフェースです。run()メソッドを実装することで、非同期で処理を実行できます。ラムダ式を使えば、コードをすっきり書くことができます。


Thread thread = new Thread(() -> {
    System.out.println("スレッドで処理を実行中...");
});
thread.start();

このように、従来は匿名クラスで長々と書いていたコードが、ラムダ式を使うことで数行にまとまります。

2. Callableとは?戻り値が欲しいときのスレッド処理

2. Callableとは?戻り値が欲しいときのスレッド処理
2. Callableとは?戻り値が欲しいときのスレッド処理

Callableは、Runnableとよく似ていますが、戻り値を返せるという違いがあります。Runnableでは戻り値がないのに対して、Callableは処理結果を返すことができます。


Callable<String> task = () -> {
    return "スレッド完了!";
};

このように、Callableはラムダ式でも記述でき、ExecutorServiceと組み合わせて実行します。

3. ExecutorServiceでスレッドを実行する方法

3. ExecutorServiceでスレッドを実行する方法
3. ExecutorServiceでスレッドを実行する方法

CallableThreadで直接実行できないため、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の違いを比較

4. RunnableとCallableの違いを比較
4. RunnableとCallableの違いを比較

RunnableCallableの違いを簡単に比較してみましょう。

項目 Runnable Callable
戻り値 なし あり
例外処理 チェック例外をスローできない チェック例外をスローできる
実行方法 Thread、Executor Executor経由
利用シーン 簡単な並列処理 戻り値が必要な処理

5. Javaのラムダ式はRunnable・Callableと相性抜群

5. Javaのラムダ式はRunnable・Callableと相性抜群
5. Javaのラムダ式はRunnable・Callableと相性抜群

RunnableCallableはどちらも「関数型インターフェース」なので、Javaのラムダ式と相性が良いです。関数型インターフェースとは、抽象メソッドが1つだけのインターフェースのことです。

つまり、() -> { 処理 }の形でラムダ式を使うことができ、より簡潔にスレッド処理が書けるようになります。

6. スレッドの非同期処理で活躍するJavaのラムダ式

6. スレッドの非同期処理で活躍するJavaのラムダ式
6. スレッドの非同期処理で活躍するJavaのラムダ式

非同期処理とは、別スレッドで処理を行い、他の処理をブロックせずに並行して動かすテクニックです。GUIアプリやWebアプリでは、レスポンスを保ったまま時間のかかる処理を実行するために使われます。

JavaではThreadExecutorServiceを使った非同期処理が主流で、ラムダ式を組み合わせることで、コードがシンプルかつ読みやすくなります。

7. 複数スレッドをラムダ式で実行する例

7. 複数スレッドをラムダ式で実行する例
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の並列処理はラムダ式とともに進化した

8. Javaの並列処理はラムダ式とともに進化した
8. Javaの並列処理はラムダ式とともに進化した

昔のJavaではスレッド処理を書くのが面倒で、クラスをたくさん定義する必要がありました。しかしJava8以降、ラムダ式によってコードが非常にシンプルになり、可読性も向上しました。

RunnableCallableをラムダで使うことで、複雑な並列処理も短く書けて、メンテナンスしやすいコードになります。

これから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の並列処理は、ラムダ式を理解することで一気に扱いやすくなりますよ。」

カテゴリの一覧へ
新着記事
Springの@Transactional徹底解説!トランザクションの伝播・分離レベル・タイムアウトの基本
JavaのHashMapクラスgetメソッドの使い方を完全ガイド!初心者でもわかるjava.util入門
Thymeleafのth:fragmentを使ったテンプレートの再利用方法を完全ガイド!初心者でもわかる使い方
Javaの@PathVariableアノテーションの使い方を徹底解説!初心者でもわかるパスパラメータの基本と応用
人気記事
No.1
Java&Spring記事人気No1
Javaのラムダ式で配列を扱う!Arrays.streamの基本と注意点を初心者向けに解説
No.2
Java&Spring記事人気No2
JavaのRuntimeExceptionを完全解説!初心者でもわかるjava.langパッケージの基礎
No.3
Java&Spring記事人気No3
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.4
Java&Spring記事人気No4
JavaのIntegerクラスの使い方を完全ガイド!初心者でもわかる整数操作
No.5
Java&Spring記事人気No5
JavaのBigDecimalクラスcompareToメソッド完全ガイド!初心者でもわかる大小比較の基本
No.6
Java&Spring記事人気No6
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.7
Java&Spring記事人気No7
JavaのHttpSessionを徹底解説!初心者でもわかるセッション管理の基本
No.8
Java&Spring記事人気No8
Javaの@SuppressWarningsアノテーションの使い方を完全ガイド!初心者でもわかる警告の抑制方法