gpt4 book ai didi

java - 在 Java 中引发竞争条件

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:10:48 25 4
gpt4 key购买 nike

我必须编写一个引发竞争条件的单元测试,这样我就可以测试我是否可以稍后解决问题。问题是竞争条件很少发生,可能是因为我的电脑只有两个内核。

代码如下:

class MyDateTime {
String getColonTime() {
// datetime is some kind of lazy caching variable declared somewhere(does not matter)
if (datetime == null) {
initDateTime(); //Uses lazy to initlialize variable, takes some time
}
// Colon time stores hh:mm as string
if (datetime.colonTime == null) {
StringBuilder sb = new StringBuilder();
//Now do some steps to build the hh:mm string
//...
//set colon time
datetime.colonTime = sb.toString();
}
return datetime.colonTime;
}
}

解释:initDateTime 为 dateTime 分配一个新实例,因此 datetime.colonTime 之后为 null(因为我们想延迟初始化它,正如我之前所说)。现在,如果线程 A 进入该方法,然后调度程序就在它可以运行 initDateTime() 之前停止它。线程 B 现在运行 getColonTime(),发现 datetime 仍然为 null 并对其进行初始化。 datetime.colonTime 为空,因此第二个 if block 被执行并且 datetime.colonTime 获取 StringBuilder 的值。如果调度程序停止此行和 return 语句之间的线程并恢复线程 A,则会发生以下情况:由于 A 在调用 initDateTime 之前停止,因此 A 现在调用 initDateTime(),这会重置日期时间对象,再次将 datetime.colonTime 设置为 null。然后线程A会进入第二个if block ,但是调度器会在datetime.colonTime = sb.toString();之前中断A叫做。作为结论,dateTime.colonTime 仍然是空的。现在调度程序恢复 B 并且该方法返回 null。

我试图通过让多个线程调用 getColonTime() 到 MyDateTime 的单个(最终)实例来引发竞争条件,但它只在极少数情况下失败:(有任何关于如何编写 JUnit“测试”的提示吗?

最佳答案

正如您所提到的,竞态条件很难始终如一地重现。然而,平均法则站在你这一边。如果您创建一个测试,您预计可能会失败一百次,然后让它发生一千次,您可能会在旧代码中相当一致地捕获错误。因此,为了与 TDD 原则保持一致,您应该按照以前的方式开始编写代码,提出一个测试迭代足够多的次数以针对旧代码持续失败,然后更改为新代码并确保它不会失败.

关于java - 在 Java 中引发竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7446052/

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