6

Lock.class と MyThread.class の 2 つの異なるオブジェクトでロックを保持しているスレッド t1 が、MyThread.class.wait() を使用して MyThread.class インスタンスで待機モードになるかどうかを確認するために、このプログラムを作成しました。Lock でロックを解放しません。クラスインスタンス。なんでそうなの ?スレッドが待機モードになるか、スレッドが終了すると、取得したすべてのロックが解放されると考えていました。

public class Lock {

protected static volatile boolean STOP = true;
public static void main(String[] args) throws InterruptedException {
    MyThread myThread = new MyThread();
    Thread t1 = new Thread(myThread);
    t1.start();
    while(STOP){
    }
    System.out.println("After while loop");
    /*
     * 
     */
    Thread.sleep(1000*60*2);
    /*
     * Main thread should be Blocked.
     */
    System.out.println("now calling Check()-> perhaps i would be blocked. t1 is holding lock on class instance.");
    check();
}

public static synchronized void check(){
    System.out.println("inside Lock.check()");
    String threadName = Thread.currentThread().getName();
    System.out.println("inside Lock.Check() method : CurrrentThreadName : "+ threadName);
}
}


class MyThread implements Runnable{
public MyThread() {
}

@Override
public void run() {
    try {
        System.out.println("inside Mythread's run()");
        classLocking();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static synchronized void classLocking() throws InterruptedException{
    System.out.println("inside Mythread.classLocking()");
    String threadName = Thread.currentThread().getName();
    System.out.println("inside MyThread.classLocking() : CurrrentThreadName : "+ threadName);
    /*
     * outer class locking 
     */
    synchronized (Lock.class) {
        System.out.println("I got lock on Lock.class definition");
        Lock.STOP = false;
        /*
         * Outer class lock is not released. Lock on MyThread.class instance is released.
         */
        MyThread.class.wait();
    }
}
}
4

4 に答える 4

4

あなたはそれが他のロックを解放しないということは正しいです。理由は、安全ではないからです。内部関数の呼び出し中に外部ロックを解放しても安全である場合、他のロックを保持したまま内部関数を呼び出すのはなぜですか?

関数がプログラマーの背後で取得しなかったロックを解放すると、同期された関数のロジックが破壊されます。

于 2012-07-15T18:44:42.857 に答える
0

wait()のセマンティクスは、ロックを呼び出すスレッドが別のスレッドによってロックがすでに取得されていることを認識し、一時停止され、ロックを保持しているスレッドがロックを解放したときに通知されるのを待つことです(そしてnotifyを呼び出します)。待機中に取得したすべてのロックを解放するという意味ではありません。待機の呼び出しは、アクションを実行するために必要なすべてのロックを取得する途中でスレッドが遭遇するいくつかの障壁として見ることができます。

「待機を呼び出したときに取得したすべてのロックをスレッドが解放しないのはなぜですか」という質問については、そうすると飢餓状態になりやすくなり、マルチスレッドアプリケーションの進行が遅くなると思います(すべてスレッドは、最初の待機を呼び出すときにすべてのロックを放棄し、現在待機しているロックを取得するときに最初からやり直す必要があります。したがって、スレッドはロックをめぐって恒久的な戦いになります。実際、このようなシステムでは、実行を終了できるスレッドは、必要なときにすべてのロックを解放することができます。これは起こりそうにありません)

于 2012-07-15T18:45:21.467 に答える
0

メソッドの JavaDoc からwait()

現在のスレッドは、このオブジェクトのモニターを所有している必要があります。スレッドは、このモニターの所有権を解放し、別のスレッドが、このオブジェクトのモニターで待機しているスレッドに、notifyメソッドまたはメソッドへの呼び出しを通じてウェイクアップを通知するまで待機しますnotifyAll。スレッドは、モニターの所有権を再度取得できるまで待機し、実行を再開します。

于 2012-07-15T18:48:01.217 に答える
0

はい、正しく動作しています。スレッドが待機状態になると、すべてのロックではなく、対応するロックが解放されます。それ以外の場合は、考えてみてください: 物事があなたの考えのようなものである場合、スレッドが待機すると、取得したすべてのロックが失われ、高度な順次実行が不可能になります。

于 2012-07-15T18:49:31.603 に答える