これは、クラスBufferedInputStream
がマルチスレッド使用のために設計されているためです。
protected volatile InputStream in;
それはprotected
あるので、その値はBufferedInputStream
およびそのサブクラスを含め、FilterInputStream
の任意のサブクラスによって変更することができます:ここで
は、あなたが親クラスFilterInputStream
に置かれin
の宣言を参照してください。また、volatile
と宣言されています。つまり、いずれかのスレッドが変数の値を変更すると、この変更は他のすべてのスレッドに即座に反映されます。この組み合わせは悪いです。BufferedInputStream
は、in
が変更されたときを制御または知る手段がないことを意味するためです。したがって、nullのチェックとreturn文の間で値をBufferedInputStream::getInIfOpen
に変更することもできます。これにより、nullが無駄になることを効果的にチェックします。in
の値を1回だけ読み取ってローカル変数input
にキャッシュすると、BufferedInputStream::getInIfOpen
メソッドはローカル変数が常に1つのスレッドによって所有されるため、他のスレッドからの変更に対して安全です。
例は、nullにin
を設定する、BufferedInputStream::close
であり:
public void close() throws IOException {
byte[] buffer;
while ((buffer = buf) != null) {
if (bufUpdater.compareAndSet(this, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
// Else retry in case a new buf was CASed in fill()
}
}
BufferedInputStream::getInIfOpen
実行中BufferedInputStream::close
が別のスレッドによって呼び出された場合、これは上記の競合状態をもたらすであろう。
'Eclipse'では、デバッガを' if'文で一時停止することはできません。 *エイリアス変数の理由かもしれません。ただそれをそこに投げたかった。私はもちろん、推測します。 –
@DebosmitRay:本当に 'if'文で一時停止できませんか? – rkosegi
@rkosegi Eclipseの私のバージョンでは、この問題は[this one](http://stackoverflow.com/questions/20413287/bug-with-eclipse-debuggers-stepover)に似ています。非常に一般的な出来事ではないかもしれません。そして、とにかく、私は軽いメモ(明らかに悪い冗談)でそれを意味しませんでした。 :) –