- ベストアンサー
ロックの取得とwaitメソッド
インスタンスに対してwait()メソッドを実行するには、そのインスタンスのロックを取得していなくてはならないと思っています。 method2()がエラーになるのと、method3が正常に動作するのは、 インスタンスに対するロックの有無で理解できます。 ただ、下記のソースでmethod()がエラーとならない動作が理解でき ませんでした。 このメソッドだと、メソッド単位ではロックがかかっていますが、 synchronizedでないメソッドが存在すれば別スレッドからアクセスでき るので、インスタンスに対するロックを取得しているわけではないと思 います。 私の理解が間違っているのでしょうか。 class MyClass { String str = new String("a"); public synchronized void method(){ try{ wait(); } catch (Exception e) { e.printStackTrace(); } } public void method2(){ synchronized (str) { try{ wait(); }catch(Exception e){ e.printStackTrace(); } } } public void method3(){ synchronized (this) { try{ wait(); }catch(Exception e){ e.printStackTrace(); } } } } class UseMyThread1 { public static void main(String args[]) { MyClass mc1 = new MyClass(); MyClass mc2 = new MyClass(); MyClass mc3 = new MyClass(); //mc1.method();//ここはエラーにならない System.out.println("*********"); //mc2.method2(); //ここはエラーになる System.out.println("*********"); //mc3.method3();//ここはエラーにならない } }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 もしかしたら、method3に対する理解も間違っているかもしれないので、もう少し詳しく説明します。 まず、synchronized(x)というのは、xのモニターを取得することを意味します。 モニターというのは、1つのオブジェクトに対し1つのスレッドしか取得できません。 モニターを取得しようとしたときに、他のスレッドが既にそのオブジェクトのモニターを取得していた場合は、モニターが取得できるまで待機させられます。 また、synchronizedメソッドというのは、そのメソッドを持つオブジェクトのモニターを取得することを意味します。 つまり、synchrozied(this)と同じだということです。 一方synchronizedとは関係ないメソッド等は「モニターの取得」の動作を行いません。 スレッドの待機が起こるのは、モニターを取得するときなので、他のスレッドがモニターを取得していても、synchronizedではないメソッドは実行できることになります。 なお、「モニター」というのはJAVAでの正式用語です。 わからない箇所があれば補足して下さい
お礼
回答ありがとうございます。 waitメソッドを実行するにあたってはmethod()とmethod3()は同じ動作をすることはわかりました。ただやはり気になるのは、MyClassのインスタンスを作ってmethod()を実行した場合、他のスレッドからsynchronizedでないメソッドにはアクセスができると思いますが、それでもインスタンスに対するロックを取得したことになるのでしょうか。