Java Gold SE11対策:並列処理とは何か?Javaで最初にぶつかる「ThreadとRunnable」の壁を超えよう

この記事のゴール
- 並列処理(Concurrency)ってそもそも何?
- Javaで並列処理をする方法(ThreadとRunnable)
- なぜ Runnable をわざわざ使うのか?という疑問の解消
- 「runに処理書いてるだけやん問題」に答える!
目次
1. 並列処理(Concurrency)とは?
プログラムを高速化したいとき、処理を同時に進める方法が求められます。これが並列処理(concurrency)です。
たとえば:
- A処理がファイルを読み込んでる間に、
- B処理が別のAPIを叩く
といったように、複数の作業を“同時に”動かせるのが並列処理です。
2. Javaにおける並列処理の基本:ThreadとRunnable
Javaでは、並列処理を実現するために「スレッド(Thread)」という仕組みを使います。
Thread thread = new Thread();
thread.start(); // 並列に処理が走る
このスレッドには、やらせたい処理を定義する必要があり、それを run() メソッドに書きます。
この run() をどう書くかで、2つのアプローチがあります。
3. Threadクラスを継承する方法
public class MyThread extends Thread {
public void run() {
System.out.println(“Threadを継承したやり方”);
}
}
new MyThread().start();
これは「Threadクラスを継承」して、run() メソッドをオーバーライドする方法。
ただしこの方法には弱点があります。
4. Runnableを使う方法(おすすめ)
Runnable task = new Runnable() {
public void run() {
System.out.println(“Runnableで書いたやり方”);
}
};
new Thread(task).start();
こっちはRunnable(インタフェース)を使って run() を渡すやり方です。
Javaではこちらが推奨されており、実務でもこの形をよく見ます。
5. Runnableを使う理由:「runに書くだけなのに」じゃない!
❓ わざわざ Runnable に分ける意味ある?直接 Thread 継承でもいいのでは?
というのは自然な疑問ですが、次の理由でRunnableのほうが優れています:
理由 | 説明 |
✅ 継承の制約を回避 | Javaは多重継承できないため、Thread を継承すると他のクラスが継承できなくなる |
✅ 責務の分離 | 「処理の定義(Runnable)」と「処理の実行(Thread)」を分けると、テストや再利用がしやすくなる |
✅ 実務との親和性 | ExecutorService や Future、ラムダ式との組み合わせに強い |
6. Runnableはインタフェースだから自由度が高い
Runnableは実は関数型インタフェース(抽象メソッドが1つだけ)なので、ラムダ式でも書けます:
new Thread(() -> {
System.out.println(“ラムダ式でも書ける!”);
}).start();
7. 【まとめ】
項目 | Thread継承 | Runnable実装 |
継承制限 | あり(他のクラスを継承できない) | なし |
再利用性 | 低い(処理がThreadに埋め込まれる) | 高い(Runnableとして再利用可) |
実務適性 | △ | ◎ |
推奨度 | 基本は使わない | 実務・試験ともにこちらを覚えるべき |