Javaにおけるマルチスレッドプログラミング基礎

プロセスとスレッドの概念

プロセスとスレッドは並行処理の基本単位です。例えば動画再生アプリケーションでは、アプリ起動がプロセスに対応し、映像処理、音声再生、コメント表示などの各機能が個別のスレッドで実行されます。プロセスは実行中のプログラムでシステムリソース割当の基本単位、スレッドはCPUスケジューリングの基本単位です。

重要な特性

  • スレッドは独立した実行パスを形成
  • 明示的にスレッドを作成しなくてもmainスレッド(ユーザースレッド)やGCスレッド(デーモンスレッド)が存在
  • 同一リソースへのアクセス時には競合状態が発生する可能性あり
  • 各スレッドは固有の作業領域を持ち、データ不整合のリスクあり

スレッド生成方法

Javaにおけるスレッド生成の主要な手法:

  1. Threadクラスの継承とrun()メソッドのオーバーライド
  2. Runnableインターフェースの実装とThreadへの渡し
  3. Callableインターフェースの実装とFutureTaskの利用

実装上の注意点

  • スレッド起動は即時実行を保証せずCPUスケジューリングに依存
  • run()メソッド直接呼び出しではスレッド生成されない
  • Runnable実装が推奨(単一継承制約回避のため)
  • Callable実装では戻り値と例外処理が可能

スレッド状態遷移

スレッドライフサイクルの基本状態:

状態説明
NEWThreadインスタンス生成直後
RUNNABLEstart()呼び出し後
RUNNINGCPUリソース獲得中
BLOCKEDsleep/wait/lockによる待機
TERMINATED実行完了後

基本操作メソッド

  • sleep(): 指定時間スレッド停止
  • yield(): 実行権を他スレッドへ譲渡
  • join(): 他スレッドの終了待機
  • interrupt(): スレッド中断(非推奨)

スレッド制御実装例

安全なスレッド停止

public class SafeTermination implements Runnable {
  private volatile boolean active = true;
  
  public void run() {
    int counter = 0;
    while(active) {
      System.out.println("実行中: " + counter++);
    }
  }
  
  public void terminate() {
    active = false;
  }
  
  public static void main(String[] args) {
    SafeTermination task = new SafeTermination();
    new Thread(task).start();
    
    for(int i=0; i<=100; i++) {
      System.out.println("メイン: " + i);
      if(i == 90) {
        task.terminate();
        System.out.println("停止指示発行");
      }
    }
  }
}

スレッド優先制御

public class PriorityControl {
  public static void main(String[] args) throws Exception {
    Thread vip = new Thread(() -> {
      for(int i=0; i<100; i++) {
        try {
          Thread.sleep(10);
          System.out.println("優先処理: " + i);
        } catch(InterruptedException e) {
          e.printStackTrace();
        }
      }
    });
    
    vip.start();
    
    for(int j=0; j<100; j++) {
      if(j == 50) vip.join();
      System.out.println("通常処理: " + j);
    }
  }
}

スレッド同期機構

共有リソースアクセス時の競合回避策:

  • synchronizedキーワードによるメソッド/ブロック同期
  • 明示的ロック(Lockインターフェース)
  • アトミック操作(Atomicクラス群)

デッドロック発生条件

  1. 相互排除: リソース排他制御
  2. 保持待機: 獲得リソース保持中の追加要求
  3. 強制解除不可: リソースの強制解放不可
  4. 循環待機: スレッド間の循環依存

タグ: Java マルチスレッド スレッド同期 デッドロック スレッド制御

7月20日 16:44 投稿