社内se × プログラマ × ビッグデータ

プログラミングなどITに興味があります。

マルチスレッドプログラミング - Thread class の継承

Apache spark などマルチスレッドのプログラミングを行う上で非常に便利なライブラリが登場していますが、それがあまりにも便利すぎるが故に、それ以前のマルチスレッドプログラミングについても学んでおきたいところです。
そもそも Apache spark のライブラリ自体が、内部的には元来のマルチスレッド手法を踏襲していたりもするところもあると思いますので、やはり知っておいた方が、より理解も深まるだろうと思います。

Java でマルチスレッドプログラミングを行う方法はいくつかあると思いますが、最も基本的な?ものは、Thread クラスを継承して使用するやり方かと思います。
Thread クラスを継承したクラスのインスタンスを生成し、start メソッドを実行することで、新たなスレッドを開始することができます。

f:id:blueskyarea:20170815010150p:plain

以下はどこにでもありそうな簡単なサンプルです。
インスタンス生成時に渡された intervalMs の値 sleep するだけのスレッドです。

public class MyThread extends Thread {
  private long intervalMs;
  private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

  public MyThread(long intervalMs) {
    this.intervalMs = intervalMs;
  }

  @Override
  public void run() {
    System.out.printf(dateFormat.format(new Date()) + " [%s] my-thread startging.\n", Thread.currentThread().toString());
    try {
      Thread.sleep(intervalMs);
    } catch (InterruptedException ie) {
      // nothing to do
    }
    System.out.printf(dateFormat.format(new Date()) + " [%s] my-thread ending.\n", Thread.currentThread().toString());
  }
}

これを main メソッドから呼び出します。
5秒 sleep するスレッドと、10秒 sleep するスレッドを生成しています。

public static void main(String args[]) {
  SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
  System.out.printf(dateFormat.format(new Date()) + " main thread at startging.\n", Thread.currentThread().toString());
  MyThread myThread1 = new MyThread(5000);
  myThread1.start();
  MyThread myThread2 = new MyThread(10000);
  myThread2.start();
  System.out.printf(dateFormat.format(new Date()) + " main thread at ending, actually waiting my-thread ending.\n", Thread.currentThread().toString());
}

結果は以下のようになりました。

01:06:36 main thread at startging.
01:06:36 [Thread[Thread-0,5,main]] my-thread startging.
01:06:36 main thread at ending, actually waiting my-thread ending.
01:06:36 [Thread[Thread-1,5,main]] my-thread startging.
01:06:41 [Thread[Thread-0,5,main]] my-thread ending.
01:06:46 [Thread[Thread-1,5,main]] my-thread ending.

main スレッドは直ちに最後の行に到達していますが、スレッドは直ちに終了はせずに、すべての my-thread が終了するまで待ってくれています。

まとめ

1. Thread クラスを継承した独自のスレッド用のクラスを生成する。
2. run() 内に実際に実行させたい処理を書く。
3. start() でスレッド開始する。