1

私はかなり長い間Javaの内部を研究してきました。Java でスレッド化/ロックがどのように行われるかを学び、理解したいと思っています。

したがって、同期されたメソッドまたは同期されたブロックにアクセスするには、スレッドは最初にオブジェクトのロックを取得する必要があります。さて、ここに私がもう少し光が必要なものがあります。

では、スレッドがオブジェクトのロックを取得するたびに、内部でセマフォの値をインクリメントするのでしょうか? 答えが「はい」の場合は、このシナリオを見てみましょう。

class ABC{ 

    public void method_1(){
        synchronized(xyz){
            ....
        }
    }

    public void method_2(){
        ...
        synchronized(xyz){
            ....
        }
    }
}

したがって、スレッド 1 とスレッド 2 の 2 つのスレッドがあるとします。スレッド 1 が最初にmethod_1に入り、最初に xyz のロックを取得したと仮定します。そして、Thread2が method_2に入り、xyz のロックを取得しようとします。何が起こるか?(私に言わせれば、Thread2 は、オブジェクトのセマフォ値が 0 より大きいことが判明したため、ブロックされます)

私の推論が正しいかどうか教えてください。

4

3 に答える 3

1

他の回答はあなたの質問にほとんど答えていますが、さらに読むために私はお勧めします: Java Concurrency In Practice

于 2010-02-21T10:11:58.383 に答える
1

スレッドがオブジェクトのロックを取得するたびに、セマフォの値を内部的にインクリメントしますか?

実装固有ですが、可能性は低いです。すべてのロックは 1 回しか取得できないため、カウンターは必要ありません。シンプルなトグルで十分です。すべてのロックは、それを所有するスレッド (または null) への参照を保持していると仮定します。

更新: 実際には、それよりもかなり複雑です。ロックは、ロックを待機しているスレッドのリストも維持する必要があります。また、スレッドは、待機/通知メカニズムを介してロックを一時的に解放できます (したがって、最終的にはエントリ カウンターが存在します)。その上、ロック管理はパフォーマンスに大きな影響を与えるため、あらゆる種類の最適化が行われています。JVM ロックに取り組んでいる人によるこの興味深いブログを見つけました。

したがって、スレッド 1 とスレッド 2 の 2 つのスレッドがあるとします。スレッド 1 が最初に method_1 に入り、最初に xyz のロックを取得したと仮定します。そして、Thread2 が method_2 に入り、xyz のロックを取得しようとします。何が起こるか?

はい、スレッド 2 はブロックされ、最終的にロックを取得できるまで待ちます。

于 2010-02-21T06:21:55.477 に答える
1

あなたの推論はおおむね正しいです。スレッド 2 はブロックされ、(少なくとも) スレッド 1 がミューテックスを解放するまでブロックされたままになります。

ただし、ロックは通常、単純なカウンターを備えた従来のセマフォを使用して実装されていません。通常、オブジェクトが再入可能にロックされている場合 (例: Thread1xyzがそのオブジェクトのロックを既に保持しているときにロックを試みた場合)、またはロックの競合がある場合 (例:スレッド 1 がロックしているときにスレッド 2 がロックしようとした場合xyz)。

しかし、Java ロックの実装の詳細について気にする必要はありません...自分で JVM を実装する場合を除きます!

于 2010-02-21T06:25:38.283 に答える