Java マルチスレッド完全解説:概念、ライフサイクル、実践コード例
Java アプリケーションでは複数のタスクを同時に実行する必要がよくあります。このチュートリアルでは、シングルスレッドとマルチスレッド実行の違い、スレッドのライフサイクル、同期技術、各概念を説明する実践的なコード例を解説します。
シングルスレッドとは?
Java のシングルスレッドは最小の実行単位です。Java ランタイムはアプリケーション開始時に ユーザースレッド を作成し、必要に応じて追加のユーザーまたは デーモンスレッド を追加できます。デーモンスレッドはバックグラウンドで実行され、JVM の終了を妨げません。
シングルスレッドの例:
package demotest;
public class GuruThread {
public static void main(String[] args) {
System.out.println("Single Thread");
}
}
シングルスレッド実行の利点:
- オーバーヘッドが最小—実行コンテキストが1つだけ
- デバッグと保守がシンプル
Java のマルチスレッドとは?
マルチスレッドでは、2つ以上のスレッドを並行実行し、CPU 利用率を最大化します。スレッドは同じメモリ空間を共有するため、コンテキストスイッチが高速でメモリ使用量が低く抑えられます。
2つの並行スレッド作成例:
package demotest;
public class GuruThread1 implements Runnable {
public static void main(String[] args) {
Thread guruThread1 = new Thread("Guru1");
Thread guruThread2 = new Thread("Guru2");
guruThread1.start();
guruThread2.start();
System.out.println("Thread names are following:");
System.out.println(guruThread1.getName());
System.out.println(guruThread2.getName());
}
@Override
public void run() {
// スレッドロジック
}
}
マルチスレッドの利点:
- ノンブロッキング UI とバックグラウンド処理
- 耐障害性—1つのスレッドの例外が他を止めない
Java のスレッドライフサイクル
スレッドライフサイクルは5つの明確な状態で構成されます:
- New – インスタンス化されたが未開始
- Runnable – 開始済みで実行準備完了
- Running – 積極的に実行中
- Waiting – 特定イベントまで一時停止
- Dead – 実行完了
主要スレッドメソッド
| メソッド | 説明 |
|---|---|
| start() | スレッド実行開始。JVM が run() を呼び出す |
| sleep(long milliseconds) | 現在のスレッドを指定時間一時停止 |
| getName() | スレッド名を返す |
| setPriority(int newPriority) | スレッド優先度を調整(1-10) |
| yield() | スケジューラに現在スレッドの一時停止を提案 |
実践的なスレッド例
以下はスレッド作成、優先度調整、スリープを示す簡潔な例です。
package demotest;
public class ThreadExample1 implements Runnable {
@Override
public void run() {
// スレッド作業
}
public static void main(String[] args) {
Thread guruThread1 = new Thread();
guruThread1.start();
try {
Thread.sleep(1000); // 1秒一時停止
} catch (InterruptedException e) {
e.printStackTrace();
}
guruThread1.setPriority(1);
System.out.println(guruThread1.getPriority());
System.out.println("Thread Running");
}
}
出力例:
スレッド同期
複数スレッドが共有リソースにアクセスする場合、同期でデータ整合性を確保します。Java では synchronized キーワードでクリティカルセクションをラップし、排他アクセスを保証します。
synchronized(object) {
// 同期ブロック
}
高度なマルチスレッド例
以下は2つのスレッドを作成し、それぞれが名前とカウンタを1秒遅延で出力するより高度な例です。
package demotest;
public class GuruThread2 {
public static void main(String[] args) {
GuruThread3 threadGuru1 = new GuruThread3("guru1");
threadGuru1.start();
GuruThread3 threadGuru2 = new GuruThread3("guru2");
threadGuru2.start();
}
}
class GuruThread3 implements Runnable {
private Thread guruthread;
private String guruname;
GuruThread3(String name) {
this.guruname = name;
}
@Override
public void run() {
System.out.println("Thread running " + guruname);
for (int i = 0; i < 4; i++) {
System.out.println(i);
System.out.println(guruname);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread has been interrupted");
}
}
}
public void start() {
System.out.println("Thread started");
if (guruthread == null) {
guruthread = new Thread(this, guruname);
guruthread.start();
}
}
}
典型的な出力(添付画像で説明):
まとめ
- マルチスレッドでブロッキング呼び出しから解放され、並行操作が可能
- スレッドライフサイクル—New, Runnable, Running, Waiting, Dead—がスレッドの通過状態を定義
- スレッドがデータを共有する際、同期がレースコンディション防止に必須
- スレッド作成、ライフサイクル管理、同期の理解を深める実践コード例
Java
- C++関数を実例で徹底解説:基本から応用まで
- C#コレクション実践チュートリアル:実例で学ぶ柔軟なデータ管理
- C++マルチスレッド完全ガイド:効率的な並行プログラミング
- Java Hello World:最初のプログラム
- Java String.indexOf()マスター:部分文字列検索と実践例
- Java String.charAt()完全解説:構文、戻り値、例外、実例
- Java String.compareTo()マスター:構文、ユースケース、実践例
- Java コンストラクタオーバーロード完全解説:実践コード例付き
- Javaで素数判定を行うプログラム
- Javaで挿入ソート:わかりやすい例とステップバイステップガイド
- Javaで選択ソート:ステップバイステップ例と完全コード