0
static ConcurrentHashMap k;

X x; 
//line 3: 
synchronized(k){ x = k.get("LL");}

// line 5 

// line 12: 
synchronized(k){if(x.b){x.b = false;}} 

「k」は共有マップです。スレッド1がライン5にあるとき、最初のスレッドはライン3を通過し、2番目のスレッドはライン3を通過します。スレッド1はxbをfalseに変更します。スレッド2は何のxbを見ますか?5行目は、スレッド1が2番目の同期ブロックに入る前にスレッド2がxを取得することを示しています。

4

2 に答える 2

2

「最初のスレッド」と「2番目のスレッド」という用語をやや過剰に指定しました。synchronizedあなたの質問は、最初のブロックに入る最初のスレッドが2番目のブロックに入る最初のスレッドでもあることを前提としていますsynchronizedが、それを期待する理由は本当にありません.

ただし、最初のsynchronizedブロックはあまり関連性や興味深いことは何もしません — コード スニペットには mutatesはなくk、最初のsynchronizedブロックは単にそれにアクセスするだけです — したがって、それが であるという事実は無視しsynchronizedます。これにより、定義が少し単純化されます。ここで、「最初のスレッド」は 2 番目のsynchronizedブロックに入る最初のスレッドを意味し、「2 番目のスレッド」は 2 番目のsynchronizedブロックに入る 2 番目のスレッドを意味します。(ここまででよろしいですか?) その定義の話は外れました。. .

x.b他のスレッドが入って設定される可能性がないと仮定すると、trueまたは、さらに言えば、引用したスニペットの後のコードで最初のスレッドがそうする可能性がないと仮定すると、同様に、2つのスレッドが完全に異なる可能性はありません他の場所で起こっていることが原因で の結果k.get("LL")— 2 番目のスレッドは、単純に予想されるように と表示x.bされます。falseそれの訳は

あるアクションが別のアクションの前に発生する場合、最初のアクションは 2 番目のアクションよりも前に表示され、順序付けされます。

モニターのロック解除は、そのモニターの後続のすべてのロックの前に発生します。

(上記の引用はどちらも、The Java Language Specification , Java SE 7 Editionの§17.5.5からのものです。形式については、そのセクションとその前のセクションを参照してください。)

于 2012-11-04T03:25:06.420 に答える
1

説明は正確ではありませんが、これが私が理解していることです。

スレッド 1 は 5 行目 (既に 3 行目まで) にあり、まだ 12 行目に到達していないため (スレッド 1 は 3 から 12 の間のどこかで xb を false に設定します)、スレッド 2 は xb をスレッド 1 が設定したものと見なす必要があります。それは(これは偽です)。スレッド 2 が実際に行 3 で xb を参照することを気にかけていることはわかりませんが、行 5 (私には表示されません) が同期されていない理由は明らかではありませんが、それを false に設定する行 12 は同期されています。

于 2012-11-04T03:29:32.957 に答える