3

私のコードは私に問題を与えます。

私のコードは、HogeクラスIllegalMonitorStateExceptionにあります。setStr

に変わりHoge.classます。私のコードは正しく終了しました!thissetStr

しかし、なぜそれは正常に終了したのですか?

    public class Sample {
        static Hoge gh = new Hoge();
        static Hoge gh2 = new Hoge();

        public static void main(String[] args) {

            new Thread() {
                private Hoge h2 = gh;
                public void run() {

                    System.out.println("start initialize");
                    h2.setStr("BazzBazz");
                    System.out.println("end   initialize");

                    System.out.println("start thread 1");
                    System.out.println(h2.getStr("thread-1"));
                    System.out.println("end   thread 1");
                }
            }.start();

            new Thread() {
                private Hoge h2 = gh2;

                public void run() {
                    System.out.println("start thread 2");
                    System.out.println(h2.getStr("thread-2"));
                    System.out.println("end   thread 2");
                }
            }.start();
        }
    }

    class Hoge {
        private String fuga = "fugafuga";

        public void setStr(String str) {
            synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
                fuga = str;
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        String getStr(String suffix) {
            synchronized(Hoge.class) {
                return suffix+ fuga;
            }
        }
    }
4

2 に答える 2

2

とは違うのでthis、Hogeのインスタンスです。ghgh2this

したがって、を使用する場合、 2つの異なるロックを使用するのでHoge.classはなく、1つの同期ロックはありません。this

于 2013-03-23T08:37:54.750 に答える
2

メソッドsetStrは次のようになります。

public void setStr(String str) {
            synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
                fuga = str;
                try {
                    Hoge.class.wait();//call wait on Hoge.class 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

Hoge.clas.wait()の代わりに使用する必要がありwait()ます。なんで?
なぜなら、wait()に関するOracleのドキュメントで指定されているように:

このメソッドは、このオブジェクトのモニターの所有者であるスレッドによってのみ呼び出される必要があります。

すなわちthread can't invoke a wait on an object until it owns that object's lock。それ以外の場合はスローされIllegalMonitorStateExceptionます。ここでは、Classと呼ばれるHogeのオブジェクト(つまりHoge.class)のロックを取得していますが、 ( )の現在のオブジェクトをclass level lock呼び出していました。だからそれはにつながっていた。そのため、現在のオブジェクト()のロックを取得したときにコードが正常に機能していました。その場合、現在のオブジェクト( )自体で呼び出されたためです。waitHogethisIllegalMonitorStateExceptionthiswait()this

于 2013-03-23T08:41:52.090 に答える