遅延初期化がスレッドセーフかどうかをテストしたいので、私のコードは次のとおりです。
package LazyInit;
import java.util.Random;
public class UnThreadSafeLazyInit {
private ExpensiveObject instance = null;
public ExpensiveObject getInstance() {
if (null == instance) {
instance = new ExpensiveObject();
}
System.out.println("instance=" + instance);
return instance;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 0; i < 5; i++) {
UnThreadSafeLazyInit init = new UnThreadSafeLazyInit();
Task t1 = init.new Task();
Task t2 = init.new Task();
t1.start();
t2.start();
try {
Thread.sleep(4000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(t1.getInstance() == t2.getInstance());
}
}
static class ExpensiveObject {
}
class Task extends Thread {
private ExpensiveObject instance = null;
private Random rand = new Random(47);
public void setInstance () {
this.instance = UnThreadSafeLazyInit.this.getInstance();
}
public ExpensiveObject getInstance() {
return instance;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(rand.nextInt(1000));
} catch (Exception e) {
e.printStackTrace();
}
setInstance();
}
}
}
new
私のコードでは、 2 つの Thead タスクを呼び出すたびに、競合状態以降、この 2 つが ExpensiveObject への同じ参照ではない可能public ExpensiveObject getInstance()
性があることを証明します。実行するinstance
と、常に で戻ります。私が知っているように、関数を使用しないと、遅延初期化に競合状態が存在するため、false が返される可能性があります。どのコードがエラーであるかを調べる必要があります。ありがとうございました。true
t1.getInstance() == t1.getInstance()
synchronized
public ExpensiveObject getInstance()