Threadクラスをextendsして public void run(); メソッドを実装します。
RunPrintThread.javaの実行例 |
|
既に他のクラスをextendsしている場合には、上記の Threadクラスをextendsする方法は取ることができません。 その場合は、Runnable インターフェイスをimplementsします。
RunPrintThread2.javaの実行例 |
|
スレッドを一時停止させるには、Threadクラスのsleep()メソッドを使います。 メソッドの引数には一時停止させたい時間をミリ秒単位の整数で指定します。 一時停止中にInterruptExceptionが起きる可能性があるので、tryで 囲んでおく必要があります。
RunIntervalThread.javaの実行例 |
|
複数のスレッドが、特定のインスタンスを同時に操作すると、 場合により想定していない動作を引き起こすことがあります。 このような状況を「競合状態」(Race Condition)と呼びます。 同時に操作してはいけない部分を「きわどい領域」(Critical Section)と 呼び、また、同時に操作してはいけない部分を同時にアクセスできない ようにすることを「排他制御」(Mutual Exclusion)と呼びます。
RunBadBank.javaの実行例 |
|
RunBadBank.javaを実行させると、場合により表示されるものが異なります。 競合状態が起きて、moneyが負の値になった場合にmoneyの値が表示されます。 "money=0"と表示されるのは if 文の判定のときにmoneyが負であったにも かかわらず、表示しようとしたときは0になったことを意味します。 また、何も表示されない場合でも、moneyが1000を超えた値になっている 場合がありえます。
BadBankクラスの代わりに、つぎのようなBankクラスやBank2クラスを 使うと正しく動作します。
synchronized (式) {...}で囲んだ、{ ... }部分のはロックが設定されて、 ロックを取得したスレッド1個しか同時には実行できません。 (式)の部分は、ロックを設定するインスタンスをあたえます。 インスタンス毎にロックが設定されます。
メソッドの先頭に synchronizedを宣言すると、そのメソッドは thisをロックを設定するためのインスタンスにしてメソッド 全体をsynchronizedにしたことになります。
synchronized void method() { ... } |
= | void method() { synchronized (this) { ... } } |
実行させると、aliceがspoonを、ベティがforkを持った瞬間に デッドロックが発生してしまいます。
RunEater.javaの実行例 |
|
提出〆切は、次回の講義の開始時刻です。
提出先 | http://ynitta.com/class/network/local/handin/list.php?id=kadai4a |
---|---|
提出ファイル | RunBank.java, ClientBank.java Bank.java |
コメント欄 | なし |
RunBadBank.javaを動作させて、計算を間違うことを確認して下さい。
その後、RunBadBank.javaを変更して RunBank.javaを作成して下さい。 ClientBadBankやBadBankの代わりにClientBankやBankを呼び出すものとします。 Bank.javaにcheck()メソッドの定義と呼び出しを追加して、 正しく動作することを確認して下さい。 check()メソッドの呼び出しを追加する場所は、BadBank.javaと同じく withdraw()メソッド内です。
提出先 | http://ynitta.com/class/network/local/handin/list.php?id=kadai4b |
---|---|
提出ファイル | 書き換えてデッドロックが起きなくなったEater.java |
コメント欄 | なし |
RunEater.javaを動作させて、デッドロックが起きることを確認して下さい。 デッドロックが起きた場合はCtl-C (Controlキーを押しながらcキーを押す) でプログラムの実行を中断して下さい。
RunEater.java や Eater.java を書き換えて、デッドロックが起きないようにして下さい。 (ヒント: アリスとベティが共通のオブジェクトでsynchronizeすればよい。 それにはRunEater.javaのmainで
Object obj = new Object(); new Thread(new Eater("alice",spoon,fork,obj)).start(); new Thread(new Eater("betty",fork,spoon,obj)).start();とやって、ベティがアリスと同じオブジェクトを参照できるようにする。)
変更したプログラムでデッドロックが起きないことを確認して下さい。
提出先 | http://ynitta.com/class/network/local/handin/list.php?id=kadai4c |
---|---|
提出ファイル | LineCount.javaとRunLineCount.java |
コメント欄 |
0個、1個、2個以上のファイルをコマンドラインで指定して実行させた実行結果
[実行例] $ java RunLineCount $ java RunLineCount Eater.java $ java RunLineCount Eater.java RunEater.java Bank.java |
「テキストファイルのパス」(=ファイル名)がコマンド引数で与えられると、 各ファイル毎に何行あるかを数えてファイル名と共に表示するプログラム RunLineCount.javaを作成しなさい。 「テキストファイルのパス」は複数指定されることがある。 ファイル毎に、スレッドを作って並行に行を数えること (Runnableをimplementしたクラス LineCountを用意すること)。
RunLineCount.javaの実行例 |
|