gpt4 book ai didi

java - 我想测试延迟初始化是否是线程安全的

转载 作者:行者123 更新时间:2023-12-01 23:49:35 25 4
gpt4 key购买 nike

我想测试延迟初始化是否是线程安全的,所以我的代码如下:

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 ExpenseObject getInstance(),以证明这两个实例自竞争条件以来,可能对 ExpenseObject 的引用不同。当我运行它时,它总是通过 t1.getInstance() == t1.getInstance() 返回 true。据我所知,如果我不同步函数public ExpenseObject getInstance(),它可能会返回 false,因为延迟初始化中存在竞争条件。我需要找出哪个代码是错误的。谢谢。

最佳答案

仅通过检查代码,它不是线程安全的。您遇到的问题是,许多毫秒的延迟对于计算机来说是一个巨大的时间,并且您非常非常不可能在这种类型的测试中发现问题。

例如,更新 volatile 字段与其他线程可见之间的典型延迟约为 5 纳秒。大约这么长时间以来,您的解决方案都不是线程安全的。您最多需要等待 1,000,000,000 纳秒才能查看是否遇到问题。

这就像试图看看持续 5 秒的烟花是否燃放,但闭上眼睛 317 年后才得出没有烟花的结论。

关于java - 我想测试延迟初始化是否是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16505412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com