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 つのスレッド Producer と Consumer を 定義している.各々クラスとして実現し,クラス 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 のようになる.
CPU は,通常 1 つであるが,この 2 つのスレッドを時分割で切り替えている. このようなスレッドを プリエンプティブ スレッド (preemptive thread) という. Java の言語仕様では,このようなスレッドは必ずしも仮定されていないが, 本稿では,プリエンプティブスレッドを仮定する.