#topicpath
----

なんとなく、後回しにしてきたマルチスレッドプログラミングなんですが、SWTの勉強などGUIプログラミングをやってると、どうしても知識が必要だなって思えてきまして、ちょっと勉強中です。

まだ全然わかってないんですが、いろいろメモ。

#contents


*** InterruptedException が発生するタイミング [#aafb9810]
途中。
// Object#wait()
// Thread#sleep()
// Thread#join()
//に対してThread#interrupt()が呼ばれたとき。


*** synchronizedにすることで、どこが同期化されるのか。 [#b25b1ce5]
下のクラスはsynchronizedのメソッドとそうでないメソッドがあります。
 public class Data {
  public synchronized void syncExecute() {
   System.out.println("syncExecute実行中......");
   try {
    Thread.sleep(3000);
   } catch (InterruptedException e) {
   }
 
   System.out.println("syncExecute実行終了");
  }
 
  public void execute() {
   System.out.println("execute実行");
  }
 }

それぞれのメソッドを呼び出すスレッドがあるとします。
 class SyncThread extends Thread {
  private Data data;
  public SyncThread(Data data) {
   this.data = data;
  }
  public void run() {
   data.syncExecute();
  }
 }
 
 class TestThread extends Thread {
  private Data data;
  public TestThread(Data data) {
   this.data = data;
  }
  public void run() {
   data.execute();
  }
 }

このスレッドを同時に実行すると、
 public class ThreadTest{
  public static void main(String[] args) {
   System.out.println("Start.");
 
   Data data = new Data();
   new SyncThread(data).start();
   new TestThread(data).start();
 
   System.out.println("End.");
  }
 }
結果は
 Start.
 End.
 syncExecute実行中......
 execute実行      <- syncExecute実行中にも実行されている
 syncExecute実行終了
ってなって、''synchronized なメソッドを実行中にもその他のメソッドは実行されています''。ってことは別のスレッドがあるインスタンスのモニタを取得している時も、「synchronizedでない」他のメソッドは実行されるって事なんですね。

んでは、先ほどのメソッドを
    public void execute() {
 -> public synchronized void execute() {
に変更すると、
 Start.
 End.
 syncExecute実行中......
 syncExecute実行終了
 execute実行
となり、同時には実行されていないことがわかります。つまり、ある一時点で、''ひとつのインスタンスに対して実行されているsynchronized メソッドはひとつである''ということが分かります((インスタンスごとですよ))。さらに''Thread#sleep()してもモニタは解放しない''ということも分かりました((解放するとしたら、sleepした瞬間別のメソッドが実行されるはず。逆にwait()メソッドの場合は、モニタは解放されます。))。

まとめると、
 synchronizedメソッドはモニタをとらないと実行できない。
ってことですね((すなわちあるインスタンスに対して、実行されているsynchronizedメソッドは一つである、か))。なんだか当たり前の結論に行き着きました。。

*** Thread#sleep()とObject#wait() [#t556a3d5]
上の結論より、
 Thread#sleep() したときにモニタは解放しない
 Object#wait() したときにモニタは解放される
となります。

そもそもThread#sleep()はモニタを取らなくても実行可能なので、モニタの解放も何もないわけです。またObject#wait()を呼ぶスレッドはそのインスタンスのモニタを取得している必要がありますが、wait()を呼び出した瞬間そのスレッドはダンマリになるわけで、そこでモニタを解放しないと、誰もそのインスタンスのnotfyAll()を呼べないことになります。
-[[Object#wait()のJavaDoc:http://java.sun.com/j2se/1.3/ja/docs/ja/api/java/lang/Object.html#wait()]]


-[[Thread#sleep()のJavaDoc:http://java.sun.com/j2se/1.3/ja/docs/ja/api/java/lang/Thread.html#sleep(long)]]




----
この記事は
#vote(おもしろかった[11],そうでもない[1])
#vote(おもしろかった[12],そうでもない[1])
- 「ひとつのインスタンスに対して実行されているsynchronized メソッドはひとつである」という言い方よりも、synchronized(hoge)内の処理は引数hogeというインスタンスのモニタを取得したスレッドしか実行できない(=synchronized内はhogeに対して一スレッドで、別のスレッドは待ち状態)ってことですね -- [[きの]] &new{2008-01-21 (月) 20:57:10};

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS