java.nio.ByteBuffer.slice()スレッドの動作?

ミルコクレム:

私はjava.nio.ByteBufferの自体はスレッドセーフではありませんことを理解しています。しかし、あなたが共有し、()スライスを経由してのByteBufferを派生を得る場合は、別のslice'dバッファを介して、複数のスレッドで同時に基本的なバッファの内容にアクセスすることができるでしょうか?この動作は標準化されていない場合、私はあなたがそれが最も一般的な仮想マシンで実行されます方法を知っているか、... APIの仕様ではこれについて何かを見つけることができませんか?

なスロー:

何かがスレッドセーフであることを文書化されていない場合は基本的に、それはありませんと仮定。何かが明示的として文書化されている場合ではないスレッドセーフであること、特に記述がない限り、密接に関連するものは、スレッドセーフであると仮定することはありません。


あなたが言及したよう、バッファはスレッドセーフではありません。これはで文書化されていますBuffer

バッファは、複数の並行スレッドで安全に使用できません。バッファは複数のスレッドによって使用される場合、バッファへのアクセスは、適切な同期によって制御されるべきです。

そして、の文書ByteBuffer延びるBuffer、上記と矛盾しません。

ここでのドキュメントが何ByteBuffer#slice()言います:

その内容は新しいバイトのバッファを作成し共有のサブシーケンスをこのバッファーのコンテンツの[追加重点を]。

新しいバッファの内容は、このバッファの現在位置から開始します。このバッファの内容を変更すると、新しいバッファに表示され、またその逆になります。二つのバッファの位置、リミット、マークの値は独立しています。【重点を追加しました]

新しいバッファの位置はゼロになり、その能力及びその限界は、このバッファ内に残っているバイトの数となり、そのマークが不定となり、そのバイト順になりますBIG_ENDIAN新しいバッファは、このバッファがダイレクトある場合に限りダイレクトになり、それが読み取り専用場合に限り、このバッファがされている場合、読み取り専用となります。

以下のような他の同様の方法、#slice(int,int)および#alignedSlice(int)、文書類似の挙動。

あなたが見ることができるように、バッファインスタンスの内容が共有されています。ドキュメントは、このように我々は自信を持って、バッファの一般的なスレッドの安全性を想定することができ、このような状況では、スレッドの安全性を追加することについては何も言及していない適用され、その、何のスレッドの安全性はありません。内容の同じサブシーケンスを共有する任意のバッファが書き込まれる場合は、他のすべてのバッファが影響を受けることになります。同時状況では、適切な外部同期せずに、これは潜在的なレース条件を意味します。

私は、これは読み取りおよび明確な(すなわち、非重複)サブへの書き込みに適用されるか正ではありませんよ。私は行動が、この場合に適用される配列に適用されるものは何でも前提としています。もちろん、それは考慮に直接バッファを取ることはありません。

すべてのビーイングが言ったことを、これにいくつかの微妙ながあります。記載されているように、各バッファは、独立した位置、リミット、マークの値を有することになります。この結果、各バッファができることである読み取る別個のスレッドによって。しかし、これは(あなたが外部同期を追加しない限り)バッファと、スレッド間の1対1のマッピングである1位置マークの値は(の場合だ少なくとも、バッファ読み取ることによってだけ変更することができるからである相対的な読み出し動作1及び巻き戻しを)。


1.私は、複数のスレッドができたと信じて読む場合は同期せずに同じ緩衝インスタンスから、場合にのみ、彼らはすべての使用絶対読み取り操作をし、マークを使用しないでください。言い換えれば、限り、スレッドのどれも、バッファの「メタ状態」を変更します。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=478393&siteId=1