私は不変オブジェクトについては一種のダミーです。マルチスレッド環境で役立ち、定義上スレッドセーフであるという考えが浮かびました。
しかし、次のコードは逆のようです!
public class ImmutableTest {
volatile ImmutableObject obj;
public static void main(String[] args) throws InterruptedException {
new ImmutableTest().execute();
}
private void execute() throws InterruptedException
{
obj = new ImmutableObject(0);
ExecutorService exec = Executors.newFixedThreadPool(50);
for(int i = 0; i < 50; i++){
exec.execute(new ImmutableRunnable(this));
}
Thread.sleep(5000);
exec.shutdown();
obj.print();
}
}
public class ImmutableRunnable implements Runnable {
ImmutableTest test;
ImmutableRunnable(ImmutableTest immutableTest) {
this.test = immutableTest;
}
public void run() {
this.test.obj = new ImmutableObject(this.test.obj.getValue());
}
}
public final class ImmutableObject {
private int n;
public ImmutableObject(int newValue) {
this.n = newValue;
if(Math.random() > .5){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void print() {
System.out.println(n);
}
public int getValue() {
return n;
}
}
スレッド セーフ環境では、結果として 50 が期待されます。しかし、そうではありません。ImmutableObject コンストラクターからランダム スリープを取り除くと、50 になります。
では、結論は?不変オブジェクトは「コンストラクターが十分に速い場合」スレッドセーフですか? または(おそらく)私は何かを誤解しましたか?
申し訳ありませんが、私の疑問を適切に説明していませんでした。これは同期に関する質問ではありません。メソッドを同期してロックを使用する方法を学びました。この質問は、不変オブジェクトと、それらのマルチスレッドとの関係に関するものです。不変オブジェクトはスレッドセーフであるため、恐れることなくスレッド間で共有できることをどこでも読みました。しかし、私見はまったく真実ではありません!!! 不変オブジェクトが異なるスレッド間で共有され、その使用を同期する必要がない例を教えてください。みんなありがとう。