並行プログラミング


並行プログラミングの目的

並行プログラミングの目的は二種類ある.一つは並列計算機の上で高速に計 算をするためのものである.もう一つは,逐次計算機上で動かすことを想定し ているが,自然に書くためである.Java における並列プログラミングは主に 後者を目的としている.

Java言語ではスレッド(thread, 「thread of control」(制御の糸)の短縮形) という単位で並列性を制御する.論理的に並列というのは,本当に並列に動く のではなく,一つの計算機上で時分割(time-sharing)に動くことも許す(とい うより,大多数の実装ではそうなっている)ことを意味する.スーパーコンピュー タ用の FORTRAN処理系などでは,for ループを書くと自動的に並列化するもの もあるが,Javaはこれらと違って明示的な(explicitな)並列実行の指定をおこ なっていて,スレッドを生成したところでのみ並列性が現われる.

Unix上のC言語でもプロセス(あるいはOSのスレッド)を生成して,並行プログ ラムを書くことができるが,Java言語ではライブラリではなく言語の中核部分 に並行プログラムを支援するための仕組みを入れているので,書きやすいし, OSに依存しない書き方ができる.

論理的に並列に書くと自然に書けるプログラムは次のようなものである.


新しいスレッドを取得する方法

Javaでは新しい制御のスレッドを手に入れる方法が2つある.

Threadクラスにはrun メソッド以外に,スレッドの実行を制御するための start,sleep(ミリ秒単位での休止) というメソッドがある.Runnableイ ンタフェースで,これらのメソッドを使うには,スレッドを生成するときに記 憶しておくか,あるいはスレッドを実行中に ThreadクラスのcurrentThreadメ ソッドでスレッドを取得する必要がある.

両方の方法で,スレッドを作るプログラムのサンプルを見てみよう.

// 2つのスレッドを作るクラス ThreadSample
public class ThreadSample {
  public static void main(String [] args){
  // Threadのサブクラス ExtnfThreadのインスタンスt1の作成
    ExtnOfThread t1 = new ExtnOfThread();
    // スレッド t1 の実行開始
    t1.start();

    // Runnableを実装(implement)したクラスのインスタンスを元に
    // Thread クラスのインスタンス t2 を作る
    Thread t2=new Thread(new ImplOfRunnable());
    // スレッド t2 の実行開始
    t2.start();
  }
}
// ThreadのサブクラスExtnOfThreadの宣言
class ExtnOfThread extends Thread{
// Threadをstartすると,このrunが呼ばれる
  public void run(){
    System.out.println("Extension of Thread running");
    // 1000ミリ秒 (=1秒)の間,スリープ(実行中断)
    // その間に別の割り込み(interrupt)に割り込まれた時は終了する
    try{sleep(1000);}
    catch(InterruptedException ie){return;}
    System.out.println("Extension of Thread exiting");
  }
}

class ImplOfRunnable implements Runnable{
  public void run(){
    System.out.println("Implementation of Runnable running");
    // このオブジェクトを実行しているスレッドをThread.currentThread()で得る
    // ことができる
    Thread th=Thread.currentThread();
    try{th.sleep(1000);}
    catch(InterruptedException ie){return;}
    System.out.println("Implementation of Runnable exiting");
  }
}
実行結果は以下のようになるだろう.
Extension of Thread running
Implementation of Runnable running
Extension of Thread exiting
Implementation of Runnable exiting
スレッドを呼び出す側は,Thread オブジェクトを作って,そのメソッド startを呼び出す.メソッド start はスレッドが動き出すための準備をした後 で,run を呼び出す.これが,スレッドの実行の主体となる.runメソッドの 実行を終えると,スレッドの実行も終わる.
Threadは並行(concurrent) に実行されると言っても,多くの場合は時分割 (time-sharing)で一度には1つのThreadしか動いていない.しかし,「複数の プロセッサを載せたマシンで」,「Java処理系が複数プロセッサを使えるよう になっている(green_threadsではなくnative_threadsを使用)」場合は,実際 に複数のプロセッサ上で同時に動くこともある.センターのUnixサーバ(4プロ セッサマシン)でJava SDK 1.4 を使っている場合は,この場合に該当する.

次に進む