next up previous
: 1 つのスレッド : オブジェクト指向プログラミング と 並行プログラミング : 並行プログラミング

プリエンプティブスレッド

以下のプログラムを考えてみよう
(ファイル名 Data.java).
public class Data {
  private int value;
  public int read() {
    return value;
  }
  public void write(int data) {
    this.value = data;
  }
  public static void main(String args[])
  {
    Data b = new Data();
    Producer p = new Producer(b);
    Consumer c = new Consumer(b);
    p.start(); c.start();
  }
}
class Producer extends Thread {
  private Data data;
  Producer(Data data) {
    this.data = data;
  }
  public void run() {
    for(int i=0; i<1000000; i++)
      data.write(i);
  }
}
class Consumer extends Thread {
  private Data data;
  Consumer(Data data) {
    this.data = data;
  }
  public void run() {
    while(true)
      System.out.println(""+data.read());
  }
}
このプログラムでは,2 つのスレッド ProducerConsumer を 定義している.各々クラスとして実現し,クラス Thread を継承している. これらのクラスを制御するクラスが Data である. このクラスは,最初に実行されるメソッド main を持っている. メソッド main は,クラス Data,クラス Consumer,クラ ス Producer の各インスタンスを生成し,スレッドとなる両クラスの インスタンスのインスタンスメソッド start を呼出し,スレッドを起 動している.

クラス Producer は,クラス Data中の値 value を インクリメントし,クラス Consumer は,クラス Data中の 値 value の値を表示し続けている.この 2 つの処理は独立に行われる.

このプログラムを実行すると以下のようになる.実行する毎に結果が異なるが, ある実行結果を紹介しよう.

6994
21966
21966
21966
21966
29475
36862
36862
36862
36862
 . . .
いくつか同じ数字が続いた後(クラス Consumerのインスタンスにより), 「自動的に」クラス Producer のインスタンスに切り替えられ,適当な時 間インクリメントされていることがわかる.

2 つのスレッドのタイムチャートを表現すると 図3 のようになる.

図 3: タイムチャート
\begin{figure}\begin{center}
\epsfile{file=fig1.eps,width=6cm,height=4cm}
\end{center}\end{figure}

CPU は,通常 1 つであるが,この 2 つのスレッドを時分割で切り替えている. このようなスレッドを プリエンプティブ スレッド (preemptive thread) という. Java の言語仕様では,このようなスレッドは必ずしも仮定されていないが, 本稿では,プリエンプティブスレッドを仮定する.





平成12年8月9日