4

SCJP試験の準備をしていますが、同期を完全に理解するのに問題があります。6行目で、mainで実行されているスレッドには「b」のロックが必要であることを読みました。なぜこのオブジェクトをロックする必要があるのですか?私の理解では、同期されたコードブロックは、常に1つのスレッドのみが入ることができる保護された領域ですか?次に進むと、mainのスレッドはこのロックを解放し、'bのスレッドがrunメソッドを完了するのを待ちます。'b'のスレッドは、メインのスレッドに完了したことを通知することを意味します。ただし、ここで特定のスレッドに通知しているようには見えません。この例は、Sierra andBatesSCJPの本からのものです。これに当てることができるどんな光でもありがたいです。ありがとう

class ThreadA {  
    public static void main(String [] args) {  
        ThreadB b = new ThreadB();  
        b.start();  

        **synchronized(b) {  //line 6**
            try {  
                System.out.println("Waiting for b to complete...");  
                b.wait();  
            } catch (InterruptedException e) {}  
                System.out.println("Total is: " + b.total);  
            }  
        }  
    }  
}

class ThreadB extends Thread {     
    int total;  

    public void run() {  
        System.out.println("K");  
        synchronized(this) {  
            for(int i=0;i<100;i++) {  
                total += i;  
            }  
            notify();  
        }  
    }  
}
4

4 に答える 4

2

Objectここでは、両方のスレッドが同じで同期しますbmain()最初にロックを取得しますが、次にを呼び出しますb.wait()。これにより、ロックが解放され、誰かが呼び出すのを待ちnotify()ますb

つまりrun()、この場合はで呼び出されるメソッドがbを呼び出すと、メソッドが再びnotify()ウェイクアップします。main()

したがって、bここでロックを取得することはそれほど重要ではありません。重要なのは、両方のスレッドが同じロックを取得することです。そうしないと、wait()/notify()連携が機能しません。

于 2012-09-22T12:43:41.787 に答える
2

6行目で、mainで実行されているスレッドには「b」のロックが必要であることを読みました。なぜこのオブジェクトをロックする必要があるのですか?

それがその行が行うことだからです。そのリソースを取得します。他のスレッドは他の同期ブロックを取得できますが、他のスレッドはそのオブジェクトのロックを取得できません。

ここで特定のスレッドに通知しているようには見えません。

これは本当です。プログラムは、どのスレッドに通知されるか、またはスレッドが通知されるかどうかさえわかりません。開発者としてのあなたは、おそらくそれが唯一のスレッドwait()であるために、通知される特定のスレッドがあると結論付けるかもしれません。

于 2012-09-22T12:43:50.730 に答える
2

これは非常にコーナーケースであり、あなたはそれをしません。
何が起こるかというと、スレッドはオブジェクトとでmain同期します。終了すると、a が発生し、その結果、ウェイクアップして続行します。 ただし、これは通常作成するコードではありません。つまり、オブジェクトを使用します。 これがどのようにコーナーケースであるかを確認するには、のループからを削除するだけです。オブジェクトで同期し、実装が終了した後に通知を生成するため、 コードは引き続き機能します。 動作は直感に反し、エラーが発生しやすくなります。ThreadBwait
ThreadBnotifymain
Threadsynchronization
notifyThreadB
ThreadThread

于 2012-09-22T12:45:17.543 に答える
0

コードはwait()メカニズムを利用して、それresultが他のによって計算されるようにしThreadBます。

line 6オブジェクトを待機するには、が画像に表示される場所にあるオブジェクトのロックを取得する必要がありますsynchronized (b)

同じプログラムを実行するためのより良い方法は、Thread#join()メソッドを使用することです。

public final void join()
            throws InterruptedException

Waits for this thread to die.
于 2012-09-22T13:20:52.813 に答える