2016-06-27 5 views
5

Javaでメンバのパラメータを処理するときにスレッドの安全性がすでに果たしているかどうかを知りたいと思います。Javaにおけるメソッドパラメータのスレッド安全性

あなたはAPI

boolean moreThanTen(long value) { 
    if(value > 10) return true; 
    else return false; 
} 

の方法この方法は、スレッドセーフであるだろうがあると?

すべてのスレッドはローカル変数に対して独自のスタックを持ち、プリミティブはすべてこのローカルスタックに格納されていると思います。

私に不安を与えているのは、longが2つの別々の読み取りであり、したがってスレッドセーフではないという事実だけです。

私の質問です:私はメソッドのパラメータが原子的にコピーされることを確認できますか?したがって、プリミティブをパラメータとして使用する場合(float/long)、ローカル変数のスレッドセーフティへのコピー中に問題になることはありませんか?

ありがとうございました。

+3

可変状態がないことは、メソッドがスレッドセーフであることを意味します。 – Andreas

答えて

8

スレッドが安全でないようにするには、複数のスレッドが共有リソース(フィールドなど)にアクセスできるようにする必要があります。

あなたの例では、共有リソースはありません(javaは値渡しの引数を渡します)ので、メソッドは安全ではありません。

thresholdが複数のスレッドからアクセス可能であり、変数へのアクセスが正しく同期されないので、この1つは安全ではないだろう:それは別のスレッドによって更新されている間

  • スレッドがthreshold変数を読んですることができます、矛盾した読み込み(long writes are not guaranteed to be atomic)が発生する可能性があります。
  • あるスレッドからの変数thresholdへの書き込みは、同期の欠如のために別のスレッドから見えないことがあります。その結果、2番目のスレッドが無効な値を読み取る可能性があります。
private long threshold; //mutable, may change 

boolean moreThanThreshold(long value) { 
    return value > threshold; //side comment: cleaner than your if/else 
} 
void setThreshold(long t) { this.threshold = t; } 
+0

あなたの例は個々の読み書きがアトミックなのでスレッドセーフです。揮発性を使用することで修正可能な可視性の問題を実証しました。これは、単語の裂けも解消します(JLS準拠のJVM上) – xTrollxDudex

+0

可視性の問題がある場合、定義上、メソッドはスレッドセーフではありません。さらに、長い書き込みは、JLSによってアトミックになることは保証されません。 – assylias

+0

* volatile * long writeは – xTrollxDudex

1

この場合にはスレッドのない問題...すべては方法独自のスタックで起こっている読み込みます。つまり、2つの読み込みであっても、他のスレッド間で共有されていないスタック内の値で起こっています。

ここでは、2つの読み取りに問題がない理由を少し詳しく説明します。

メソッドに引数を渡すときは、参照変数を渡すのではなく、参照変数のビットのコピーを渡します。 次のようなもの:3bad086a。 3bad086aは、渡されたオブジェクトに到達する方法を表します。だから我々はそれが参照の値であることを3bad086aに渡しています。 参照の値を渡していますが、オブジェクト自体ではなく参照自体を渡しています。この値は実際にCOPIEDされ、メソッドに渡されます。我々は常に参照の値のビットのコピーを渡す! プリミティブデータ型の場合、これらのビットはプリミティブデータ型自体の値を含みます。オブジェクトの場合、ビットには、JVMにオブジェクトへの到達方法を知らせるアドレスの値が格納されます。

関連する問題