2009-07-05 19 views
1

ConcurrentHashMapの助けを借りてIOをキャッシュしたいと思います。バイナリファイルの変更は、キャッシュにも反映する必要があります。キャッシュは複数のスレッドによって使用されるため、すべてのIO操作は同期されます。マップの変更は同じ​​ブロック内になります。これはおおよそ次のようになります。ConcurrentHashMap修飾子の同期

synchronized (file) { 
    file.deleteRecord(index) 
    map.remove(index); 
} 

synchronized(file) { 
    file.writeRecord(index, record); 
    map.put(index, record); 
} 

mapfileどちらもプライベートであり、キャッシュ・クラスの外から見ていません。

キャッシュ読み取り(map.get(index))が​​ブロックなしで行われる場合、スレッドセーフティが維持されますか?

前述のとおり、ConcurrentHashMapがマップの実装として使用されます。

答えて

5

です。これは基本的にConcurrentHashMapのポイントです。 the documentationから:(GET含む)

検索操作 は、一般的にブロックしないので、( を入れて、削除を含む)の更新操作で と重なっていてもよいです。検索は、最後にの の結果が反映されており、 の開始時に 更新操作が完了しています。

package documentationから:

同時コレクションは スレッドセーフですが、 単一排他ロックに支配ありません。 の特定のケースでは、の は、 の同時読み取り数と調整可能な同時書き込み数の調整可能な数値である を安全に許可します。

(それらのドキュメントページの両方が、もちろん、より多くの詳細を持っている。彼らは慎重に読む価値です。)

+0

答えを捨ててくれてありがとう。 – user133406

2

はい、スレッドの安全性は、マップ参照にConcurrentHashMapの実装のおかげでダウン保存されています。

地図に保存するオブジェクトは別の話です。

1

はい、ConcurrentHashMapはスレッドセーフなので、読み取り(または書き込み)にはあなたの部分でロックが必要ありません。

しかし、あなたの例では、あなたは以下の一連のイベントで終わるかもしれない:

file.deleteRecord(index); 
map.get(index) // returns the mapping for index even though it has been deleted from file 
map.remove(index); 

(writeRecord/PUTのために同じ)。これはあなたの場合には問題になるかもしれません。

0

ここに記載されているように、これはスレッドセーフです。これは、キャッシュへの書き込みとキャッシュからの読み込みとの間に起こりうる関係がありますが、他に何が保証​​されているかによっては意味がない可能性があります。望んでいる。

たとえば、ファイルをfsyncしない限り、レコードがディスクに書き込まれる保証はないため、ディスクからレコードを読み取ることはできません(ファイルシステムやその他の要因によって異なります)。また、の場合は、のwriteRecord/deleteRecordとマップ書き込みとマップからの読み取りの間には関係がありません。したがって、JMMは、ファイルに書き込まれたマップから何かを読み取ることを保証しません。

書面によるindexおよびrecordオブジェクトの状態は、読まれるものとなることが保証されますが、これらのいずれかが変更可能であれば、かなり役に立たない保証となります。