私は、メモリにマップされたファイル ( FileChannel.map()を介して) から構築されたByteBuffersと、メモリ内の直接 ByteBuffers を使用するものに取り組んでいます。並行性とメモリ モデルの制約を理解しようとしています。
FileChannel、ByteBuffer、MappedByteBuffer などの関連するすべての Javadoc (およびソース) を読みました。特定の ByteBuffer (および関連するサブクラス) に多数のフィールドがあり、状態がメモリ モデルから保護されていないことは明らかです。視点。そのため、特定の ByteBuffer の状態を変更するときに、そのバッファーが複数のスレッドで使用されている場合は同期する必要があります。一般的なトリックには、ThreadLocal を使用して ByteBuffer をラップする、(同期中に) 複製して同じマップされたバイトを指す新しいインスタンスを取得するなどがあります。
このシナリオを考えると:
B_all
マネージャーには、ファイル全体にマップされたバイト バッファーがあります (2 GB 未満とします)。- マネージャーは、B_all で duplicate()、position()、limit()、および slice() を呼び出して、ファイルのチャンクである新しいより小さい ByteBuffer を作成し、
B_1
これをスレッド T1 に渡します。 B_2
マネージャーは、同じマップされたバイトを指すByteBuffer を作成するためにすべて同じことを行い、これをスレッド T2 に渡します
私の質問は、T1 が B_1 に書き込み、T2 が B_2 に同時に書き込み、互いの変更を確実に確認できるかどうかです。T3 は B_all を使用してこれらのバイトを読み取り、T1 と T2 の両方からの変更を確実に確認できますか?
force() を使用して OS にページをディスクに書き込むように指示しない限り、マップされたファイルへの書き込みが必ずしもプロセス間で見られるとは限らないことを認識しています。私はそれを気にしません。この質問では、この JVM が単一のマップされたファイルを書き込む唯一のプロセスであると仮定します。
注: 私は推測を求めているわけではありません (自分で推測することはできます)。メモリ マップド ダイレクト バッファで何が保証されているか (または保証されていないか) について、決定的なものへの参照を希望します。または、実際の経験や否定的なテスト ケースがあれば、それも十分な証拠となる可能性があります。
更新:複数のスレッドが同じファイルに並行して書き込むことでいくつかのテストを行ったところ、これまでのところ、それらの書き込みは他のスレッドからすぐに見えるようです。そこまで頼れるか不安ですけどね。