【プログラミングしてみよう18】Javaのマルチスレッドで複数の処理を同時に動かす

Java

前回はラムダ式とStream APIを使って、コレクション操作をシンプルに書く方法を学びました。

今回は「マルチスレッド」について解説します。 マルチスレッドを使うことで、複数の処理を同時並行で動かすプログラムが作れるようになります。

マルチスレッドの基本

これまで作ってきたプログラムは、上から順番に1行ずつ処理を実行する「シングルスレッド」の動きをしていました。

「スレッド」とは、プログラムの処理の流れのことです。シングルスレッドでは処理が1本の流れで進みますが、「マルチスレッド」を使うことで複数の処理を同時並行で動かすことができます。たとえば、ダウンロードしながら別の作業を続ける、複数のユーザーのリクエストを同時に処理するといった場面で使われます。

Javaでスレッドを作る方法は主に2つあります。

  • Thread クラスを継承する方法
  • Runnable インターフェースを実装する方法

サンプルコード(Threadクラスを使う方法)

ファイル作成

「Java07」フォルダに MyThread.javaThreadTest.java という名前でファイルを作成します

コード入力

MyThread.java に以下のコードを入力します。

public class MyThread extends Thread {
    String name;

    MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println(name + " : " + i + "回目の処理");
        }
    }
}

ThreadTest.java に以下のコードを入力します。

public class ThreadTest {
    public static void main(String[] args) {
        MyThread t1 = new MyThread("スレッドA");
        MyThread t2 = new MyThread("スレッドB");

        t1.start();
        t2.start();
    }
}

コンパイル

javac MyThread.java ThreadTest.java

実行

java ThreadTest

実行結果は次のようになります(実行のたびに順番が変わることがあります)。

スレッドA : 1回目の処理
スレッドB : 1回目の処理
スレッドA : 2回目の処理
スレッドB : 2回目の処理
スレッドA : 3回目の処理
スレッドB : 3回目の処理

サンプルコード(Runnableインターフェースを使う方法)

ファイル作成

「Java07」フォルダに RunnableTest.java という名前でファイルを作成します

コード入力

以下のコードを入力します。

public class RunnableTest {
    public static void main(String[] args) {
        Runnable task1 = () -> {
            for (int i = 1; i <= 3; i++) {
                System.out.println("タスク1 : " + i + "回目の処理");
            }
        };

        Runnable task2 = () -> {
            for (int i = 1; i <= 3; i++) {
                System.out.println("タスク2 : " + i + "回目の処理");
            }
        };

        Thread t1 = new Thread(task1);
        Thread t2 = new Thread(task2);

        t1.start();
        t2.start();
    }
}

コンパイル

javac RunnableTest.java

実行

java RunnableTest

実行結果は次のようになります(実行のたびに順番が変わることがあります)。

タスク1 : 1回目の処理
タスク1 : 2回目の処理
タスク1 : 3回目の処理
タスク2 : 1回目の処理
タスク2 : 2回目の処理
タスク2 : 3回目の処理

コードの解説

Thread クラスを継承する方法では、run() メソッドをオーバーライドして、スレッドとして実行したい処理を書きます。スレッドを起動するには start() を呼びます。run() を直接呼び出してしまうと、新しいスレッドは作られず、通常のメソッド呼び出しとして順番に実行されてしまうため、必ず start() を使うようにしましょう。

Runnable インターフェースを使う方法では、前回学んだラムダ式で処理を簡潔に書くことができます。Runnable はメソッドが1つだけのインターフェースのため、ラムダ式で実装を渡すことができます。作成した Runnablenew Thread(task1) のように Thread に渡し、start() で起動します。Thread クラスを継承する方法と比べて、すでに別のクラスを継承しているクラスでもスレッドの処理を持たせられるというメリットがあります。

どちらのサンプルでも、実行結果の順番が毎回変わる可能性があります。これはスレッドAとスレッドBが同時に動いており、どちらが先に処理されるかをOSが管理しているためです。この順番の不確定さはマルチスレッドの重要な特徴のひとつで、複数のスレッドが同じデータを同時に書き換えようとすると意図しない結果になることがあります。これを「競合状態」と呼び、実際の開発では synchronized などの仕組みを使って対処します。

まとめ

マルチスレッドを使うことで、複数の処理を同時並行で動かすことができます。スレッドを作るには Thread クラスを継承する方法と、Runnable インターフェースを実装する方法があります。どちらも処理の内容を run() に書き、start() で起動するという点は共通です。実行結果の順番が毎回変わる点がマルチスレッドならではの動きで、複数スレッドが同じデータを扱う場合は競合状態に注意が必要です。マルチスレッドはWebサーバーやゲーム、GUIアプリなど、さまざまな場面で活用される重要な技術です。ぜひ実際に動かして、並行処理の感覚をつかんでみてください。

2026/06/27(土) ぱんまる

コメント

タイトルとURLをコピーしました