1

クラス CopyOnWriteArrayList を見て、その get(...) メソッドが同期を必要としない理由を知りました。add(...) および set(...) メソッドは、ReentrantLock を使用してミューテックス ブロック内の基になる配列を変更します。しかし、 get(...) は、同期せずに生の基になる配列を返すだけです。さて、基になる配列は volatile と宣言されています。

private volatile transient Object[] array;

しかし、揮発性を使用すると同期が冗長になる方法がわかりません。配列に格納された参照がコンパイラによってキャッシュされるのを防ぐだけです。ここで同期が必要ない理由を理解していれば、以前よりもロックの競合が少し少ないコードを書くことができます...

ありがとう、オリバー

4

2 に答える 2

1

ちょっとした「トリック」を使用します。基になる配列が変更されると、イベントのシーケンスは次のようになります。

  1. 新しい配列を作成する
  2. 新しい配列にデータを入力します
  3. クラスが保持する参照を新しい配列を指すように変更する

3 番目のステップの書き込み先private volatile transient Object[] array;- 揮発性セマンティクスのため、ステップ 3 の前に行われたすべての変更が表示されます。

したがって、新しい参照が表示されるだけでなく、新しい配列の内容も表示されます(これがトリックです)。

于 2013-04-10T13:15:39.240 に答える