我想测试延迟初始化是否是线程安全的,所以我的代码如下:
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
调用两个 Thead 任务public ExpensiveObject getInstance()
,以证明这两个instance
可能不一样引用 ExpensiveObject 以来的竞争条件。当我运行它时,它总是返回true
. t1.getInstance() == t1.getInstance()
据我所知,如果我不synchronized
使用该函数public ExpensiveObject getInstance()
,它可能会返回 false,因为延迟初始化中存在竞争条件。我需要找出哪个代码是错误的。谢谢你。