質問: Javaのメモリ共有の仕組みについて教えてください。 privateなどで宣言されたようなヒープ領域にある変数について、スレッドセーフの仕組になっていない場合はメモリ共有(データの書き換え)などが起こり得ると思いますが。 いったい、どのような仕組なのでしょうか。 クラスAにprivateで宣言したA'というオブジェクトがあった場合、A'はヒープ領域に割り当てられると思います。 その後、他のスレッドでもクラスAでの動作があり、A'がヒープ領域に割り当てられる場合、もちろんアドレスは最初に割り当てられたところとは違う箇所に割り当てられますよね? それでも、書き換えが起こるということは、Javaのなかでスレッド毎に割り当てたアドレスを管理出来てないのでしょうか? 「えーっと、A'のアドレスどこだっけ。あ、ここにA'のオブジェクトがある、きっとここかな。」みたいな感じで間違え得るのでしょうか。 それとも、アドレスを単に間違えるだけではない理由があるのでしょうか。 もし、参考になるようなネットのサイト等も教えて頂けると助かります。 宜しくお願いします。 回答を受け、少し追記します。 ・インスタンスはスレッド毎にできます。 ・「private オブジェクト名 変数名;」で宣言した変数がデータの書き換えが起こっています。 ・メインメソッドをsynchronizedにするとか、上記変数をローカル変数にするとかすれば治ります。 ただ、なぜインスタンスは別なのに起こるのかと思ってまして。 以前、springを使ったときにscopeをprototypeにしたときは問題なかったと思っており、結局インスタンスは別になるのに何が違うんだろうと。 (ここの解釈自体が間違えているのかもしれませんが。)
回答: > それでも、書き換えが起こるということは、Javaのなかでスレッド毎に割り当てたアドレスを管理出来てないのでしょうか? > 「えーっと、A'のアドレスどこだっけ。あ、ここにA'のオブジェクトがある、きっとここかな。」みたいな感じで間違え得るのでしょうか。 > それとも、アドレスを単に間違えるだけではない理由があるのでしょうか。 この文面を見た限りでは Java(JVM) が間違って書き換えてしまうと理解されているようですが、そうではありません。プログラマの実装ミスです。 質問に近いケースを考えると 1. Class A のインスタンスを1つ作成。スレッド1,2でこのAのインスタンスを参照する 2. Class A のインスタンスをスレッド1,2でそれぞれ生成。(Aのインスタンスが2つある状態) となりますが、前者は複数スレッドで1つのインスタンスを共有しているので、スレッドセーフに実装しないと意図しないデータの書き換えが起こる可能性があります。 後者はインスタンスが2つあるので書き換えられることはありません。 質問のお話しはたぶん後者のことですよね?