プログラミング応用b 第10回 『スレッド1』


 Javaでは,スレッドという単位で並行処理(複数の処理を同時に行うこと)を手軽に行う
ことができる。今回は,スレッドの基本事項を解説する。スレッドを適切に使用すると,CPU
のパワーを無駄なく利用でき,プログラムの構造もより明確になる。

【スレッドとは】
 私たちが使用しているコンピュータ上では,複数のプログラムが同時に動作している。
たとえば,学生諸君も日常的にWebブラウザやメールソフト,ワープロソフト,表計算ソ
フトなどを同時に起動して,それらを連携させて仕事をしていることであろう。
 これらのソフトは,同時に実行されているように見えるが,実際には,非常に短い時間
でCPUが実行するソフトを切り替えているだけで,1個のCPUが実行しているコードは常時
1ヶ所しかないのである。

 しかし,見かけ上とはいえ,同時並行的にプログラムを動作させるのは,多くのメリットを
持っている。たとえば,ワープロソフトで印刷中にメールソフトではメールを受信する,
といった効率的な仕事のすすめかたが可能になる。
  複数のプログラムを同時並行的に動作させることを,マルチプロセスとか,マルチタスク
と呼ぶ。

  一方,1つのプログラム内で,同時並行的に別々のコードを実行させることを,
マルチスレッド(multi thread) と呼び,同時並行的に実行される個々のコードのことを,
スレッド(thread) と呼ぶ。threadとは,英語で「糸」「織り糸」「議論の筋道」といった
意味がある。ここでのスレッドとは,「一連の実行コード」というニュアンスを持っている。
(Web上の掲示板などでは,発言とその返答からなる一連の会話のつらなりをスレッド
と呼んでいるが,これもスレッドという単語の「一連の○○のつらなり」という意味による)

●スレッドのメリット

 スレッドによって,ソフトウェアは大幅に利便性さが増す。 たとえば,多くのゲームソフト
では,ゲーム本編が実行されているときに,同時に通信を行っている。つまり,ひとつの
スレッドがゲーム本編の処理を行うと同時に,通信戦用のスレッドが通信作業を行って
いるのである。スレッド技術は,通信対戦を行うゲームでは必須と言える。
 また,Webブラウザでは複数のウィンドウを開いて多くのサイトを快適に同時表示できるが,
これはサイト毎に(場合によってはサイトを構成する htmlファイルが画像ファイル毎に)
通信を行う複数のスレッドが個別に通信を行っているおかげである。もしスレッドを
使わない場合,反応の遅いサイトを表示しようとしたWebブラウザは,受信データが
届くまで他のサイトの表示はできなくなってしまうだろう。

● main( ) メソッドを実行するスレッド

 ところで,私たちは今までスレッドを意識的に使用したことは無かった。しかし,実際
はすでにスレッドを使用しているのである。通常,Javaのプログラムはクラスの main( )
メソッドを呼び出して実行している。実は,Javaのプログラムが起動されると,スレッド
が1個生成される。そしてこの「最初のスレッド」が main( ) メソッドを呼び出す
のである。
なお,この「最初のスレッド」は,基本的には他のスレッドと同等のものであるが, main( )
メソッドを最初に実行するスレッドという特別な立場に置かれているので,メインスレ ッド
と呼ばれている。

 


【スレッドの使用例】

 では,さっそくスレッドの使用例を紹介しよう。List 1は,一見何の変哲もないプログ
ラムである。 main( ) メソッドを見よ。List 1-①~④では,MyThread型のオブジェクト
を2個生成し,それぞれの start( )というメソッドを呼び出しているにすぎない。

  そして,List 1-⑤では,100回繰り返す for ループの中でランダムな回数だけ空ループ
(何もしない繰り返し)をして時間を消費した後,"World"と表示しているだけである。なお,
List 1-⑤ で使われている Math.random( ) メソッドは, 見ての通り Math クラスの
static メソッドで, 0.0以上1.0未満の double 型の値をランダムに返してくれる乱数生成
メソッドである。main( ) メソッドはこれで終了となっている。

List 1 MyThreadTest1.java


 main( )メソッドだけ見てみると,実行結果は容易に想像できよう。100回連続して画面に"World"
と表示されるだけのはずである。しかし,実際にList 1を実行すると,

  World
  World
  Hello
  World
  Java
  World
   … (以下略)

というように,100個の"World",100個の"Hello",100個の"Java"がいりみだれて
表示される。実際に実行した結果の一部を下図に示す。これは,スレッドによる並行処理
が行われている証拠である。



 Javaでは,いろいろな資源(リソース, resource)や機能をクラスで記述・表現し,その
オブジェクトで管理する(例:ストリーム)。同様に,スレッドもクラスで記述・表現し,
オブジェクトで管理する

 List 1でスレッドを表しているのが,List1-⑥から始まる MyThread クラスである。
MyThread クラスは, Thread クラスのサブクラスになっている。このように,

  基本的にはスレッドはThreadのサブクラスとして定義する

のである。

 List 1-⑦は String 型フィールド str の定義で,List 1-⑧ はコンストラクタの定義(文字
列を引数にとって str フィールドにセットしている)である。これらは特別の意味は無い。問題は
次のList 1-⑨の部分である。
 List 1-⑨は,Thread クラスにある run( ) というメソッドをオーバライドしている。この
runメソッドのオーバライドがミソなのである。実は, Thread(およびそのサブクラス)型オブ
ジェクトの start( ) メソッドを呼ぶと, run( ) メソッドが呼び出され,並行実行される
のである。

次に進む