ローカル変数のみを使用し、インスタンス変数を使用しないだけで十分ですか。したがって、スタック上のメモリのみを使用します (スレッドごと)。
しかし、メソッドに対してローカルな新しい MyObject を作成するとどうなるでしょうか。新しいオブジェクトはヒープ上に作成されませんか? それへの参照がローカル(スレッドセーフ)であるため、スレッドセーフですか?
ローカル変数のみを使用し、インスタンス変数を使用しないだけで十分ですか。したがって、スタック上のメモリのみを使用します (スレッドごと)。
しかし、メソッドに対してローカルな新しい MyObject を作成するとどうなるでしょうか。新しいオブジェクトはヒープ上に作成されませんか? それへの参照がローカル(スレッドセーフ)であるため、スレッドセーフですか?
その特定のメソッドの変数によってのみ参照される場合(あなたが言ったように、ローカル変数です)、他のスレッドがオブジェクトへの参照を持つことはできず、変更できないため、スレッドセーフです。
あなたと私が海賊(スレッド)だと想像してください。戦利品 (オブジェクト) を島 (ヒープ) に埋め、そこへのマップ (参照) を保持します。私はたまたま戦利品を埋めるために同じ島を使用していますが、あなたが私にあなたの地図を渡すか、島中を掘りに行かない限り(ジャワ島では許可されていません)、私はあなたの隠し場所を台無しにすることはできません.
MyObject
メソッドへの呼び出しごとにヒープ上に独自のローカル インスタンスが作成されるため、newはスレッド セーフです。共通のメソッドを参照する呼び出しはありません。MyObject
N 回の呼び出しがある場合、それはヒープ上にN 個のインスタンスがあることを意味します。メソッドが終了すると、呼び出し元に返さない限り、各インスタンスは GC の対象になります。
では、質問させてください。メソッドをローカル変数に制限すると、メソッドが別のスレッドとリソースを共有できないということですか? そうでない場合、明らかにこれは一般的なスレッド セーフには十分ではありません。
別のスレッドで作成したオブジェクトを別のスレッドが変更できるかどうか心配している場合、唯一心配する必要があるのは、そのオブジェクトへの参照をスレッドから漏らさないことです。それを達成すると、オブジェクトはヒープに置かれますが、他のスレッドはそれを参照できないので問題ありません。
私の最初のステートメントに関して、インスタンス変数のないメソッドは次のとおりです。
public void methodA() {
File f = new File("/tmp/file");
//...
}
これは、2 つのスレッド間で共有リソースが存在できないという意味ではありません :-)。
他のスレッドがそのようなオブジェクト参照にアクセスする方法はありません。しかし、そのオブジェクトがスレッド セーフでない場合、全体的なスレッド セーフが損なわれます。
たとえば、MyObject が HashMap であるとします。
ヒープにある場合はスレッドセーフではないという議論は無効です。ヒープはポインター演算を介してアクセスできないため、オブジェクトが実際に格納されている場所 (ThreadLocal 以外) には影響しません。