EzThreadで簡単マルチスレッド・プログラミング


こんにちは、マルチスレッド・プログラミングって結構敷居たかいよね。
eclipseに語りかけてる高橋です...m(__)m
マルチスレッド・プログラミングとは何ぞやと言う方は、ググる(Google)か下記を参照してください。

【マルチスレッド・プログラミングとは?】
マルチスレッドとは、1つのアプリケーションソフトがスレッドと呼ばれる処理単位を複数生成し、並行して複数の処理を行なうこと。いわばアプリケーションソフト内でのマルチタスク処理。マルチタスクと同じように、CPUの処理時間を非常に短い単位に分割し、複数のスレッドに順番に割り当てることによって、複数の処理を同時に行っているようにみせている。

で、Javaにはマルチスレッド機能であるThreadクラスが存在するわけですが、プログラムを開発する際にマルチスレッドを意識したコードを書くのは意外と煩雑なのです。まず、Threadクラスを継承してrunメソッドに実装コードを書きます。

マルチスレッド・プログラミングのコード例

/** マルチスレッドで処理するプログラム */
public class Hoge extends Thread {
 private String param1;
 private String param2;
 public String result;
 // runメソッド内に記述されるビジネスロジックで利用するパラメータは
 // 別メソッドで定義する必要がある
 public void setParam(String param1, String param2) {
  this.param1 = param1;
  this.param2 = param2;
 }
 // ビジネスロジックコード(このメソッドはThread#start()メソッドから
 // マルチスレッドとして呼び出されます)
 public void run() {
  // 指定されたパラメータ(param1,param2)を結合した結果をresultに格納します。
  this.result = this.param3 + this.param2;
 }
}
/** 呼び出し元プログラム */
public class Main {
 public static void main(String[] args) {
  // スレッドA
  Hoge hoge1 = new Hoge();
  hoge1.setParam("パラメータ1","パラメータ2");
  hoge1.start();
  // スレッドB
  Hoge hoge2 = new Hoge();
  hoge2.setParam("パラメータ3","パラメータ4");
  hoge2.start();
  // スレッドA,Bの処理が完了する前に、この行以下のコードが実行されるため処理が
  // 完了したかを知る仕組みが必要になります。
  // またスレッドA,Bの処理で例外が発生した場合に、それを知る方法と例外をcatchする
  // 仕組みが必要になります
  ...
  System.out.println(hoge1.result);
  System.out.println(hoge2.result);
 }
}

Hoge(スレッドA,B)の処理状況は別スレッドで起動されてる事から、呼び出し元からは判断がつかないため、その仕組みも実装する必要が出てきます。上記コードをみても分かるとおり、Hoge(スレッドA,B)の実行結果の戻り値を呼び出し元に返す仕組みもないため開発者が実装(工夫)する必要があります。
本来の機能とマルチスレッドの機能が混在するため開発するのが、いがいーと面倒なのですね。。。


そんな悩みを解決するのが、新FwのEzThreadクラスです。
EzThreadクラスを利用すれば、通常のJavaクラスがマルチスレッドで実行することが可能になります。
また、マルチスレッドで起動している処理の状況(実行中か、正常終了したか、異常終了したか)の判別も呼び出し元プログラムで確認しすることが出来ます。
では、EzThreadを利用して通常のJavaクラスをマルチスレッドで起動するコードを見てみましょう。。。

EzThreadを利用したマルチスレッド・プログラミングのコード例

/** マルチスレッドで処理されるプログラム */
public class Hoge {
 // ビジネスロジックコード(普通のメソッド)
  public String concat(String param1, String param2) {
  // 指定されたパラメータ(param1,param2)を結合した結果をresultに格納します。
  return this.param3 + this.param2;
 }
}
/** 呼び出し元プログラム */
public class Main {
 public static void main(String[] args) {
  // スレッドA  
  // パラメータ1 : 実行対象となるインスタンス
  // パラメータ2 : 実行するメソッド名
  // パラメータ3以降 : 2のメソッドに受け渡すパラメータ)
  EzThread thread1 = EzThread.execute(new Hoge(),"concat","引数1","引数2");
  // スレッドB  
  EzThread thread2 = EzThread.execute(new Hoge(),"concat","引数1", "引数2");
  // スレッドA,Bが処理中かを確認します。
  while(thread1.isProssessing() || thread2.isProssessing()) {
   // スレッドA,Bが処理中であった場合は、1秒sleepします。
    EzThread.sleep(1000);
  }
  // スレッドAの処理が異常終了したかを確認します。
  if(thread1.isAbnormalEnd()) {
   // 処理が異常終了した時の処理
   System.out.println("スレッドAが異常終了しました");
   Throwable e = thread1.getThrowable();
   e.printStackTrace();
  }
  // スレッドBの処理が異常終了したかを確認します。
  if(thread2.isAbnormalEnd()) {
   // 処理が異常終了した時の処理
   System.out.println("スレッドBが異常終了しました");
   Throwable e = thread2.getThrowable();
   e.printStackTrace();
  }
  // スレッドA,Bが共に正常終了したかを確認します。
  if(thread1.isNormalEnd() || thread2.isNormalEnd()) {
   // スレッドA,Bが共に正常終了した時の処理。
    System.out.println(thread1.getReturn());
    System.out.println(thread2.getReturn());
  }
 }
}

これでokです。上記コードを見ると分かるとおり、ビジネスロジックを記述するHogeクラスは通常のjavaクラスですね。マルチスレッドで実行されることは、まったく意識しないつくりになってます。EzThreadは、呼び出す側のプログラムで利用します。通常のThreadの以下の問題点は、すべてクリアされているのが分かると思います。


【Threadの問題点】
・マルチスレッドで実行するプログラムがPOJOで作成可能
・スレッドの状況(実行中か、正常終了したか、異常終了したか)が呼び出し側で確認可能
・呼び出し側で「戻り値」「例外」の取得が可能


ちょー簡単ですね(^^)
EzThreadを利用すれば、Javaで日次バッチや月次バッチ等を「支店」や「営業所」毎に実行することが簡単にできますね。。。