Top / Java / スレッドプログラミング

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

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

InterruptedException? が発生するタイミング

途中。

synchronizedにすることで、どこが同期化されるのか。

下のクラスは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 メソッドはひとつであるということが分かります*1。さらにThread#sleep()してもモニタは解放しないということも分かりました*2

まとめると、

synchronizedメソッドはモニタをとらないと実行できない。

ってことですね*3。なんだか当たり前の結論に行き着きました。。

Thread#sleep()とObject#wait()

上の結論より、

Thread#sleep() したときにモニタは解放しない
Object#wait() したときにモニタは解放される

となります。

そもそもThread#sleep()はモニタを取らなくても実行可能なので、モニタの解放も何もないわけです。またObject#wait()を呼ぶスレッドはそのインスタンスのモニタを取得している必要がありますが、wait()を呼び出した瞬間そのスレッドはダンマリになるわけで、そこでモニタを解放しないと、誰もそのインスタンスのnotfyAll()を呼べないことになります。


この記事は

選択肢 投票
おもしろかった 12  
そうでもない 1  
  • 「ひとつのインスタンスに対して実行されているsynchronized メソッドはひとつである」という言い方よりも、synchronized(hoge)内の処理は引数hogeというインスタンスのモニタを取得したスレッドしか実行できない(=synchronized内はhogeに対して一スレッドで、別のスレッドは待ち状態)ってことですね -- きの? 2008-01-21 (月) 20:57:10

Top / Java / スレッドプログラミング

現在のアクセス:8112


*1 インスタンスごとですよ
*2 解放するとしたら、sleepした瞬間別のメソッドが実行されるはず。逆にwait()メソッドの場合は、モニタは解放されます。
*3 すなわちあるインスタンスに対して、実行されているsynchronizedメソッドは一つである、か

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-01-25 (水) 16:54:16 (2881d)