在Java中测试线程安全[重复]

Posted

技术标签:

【中文标题】在Java中测试线程安全[重复]【英文标题】:Testing thread-safety in Java [duplicate] 【发布时间】:2012-08-15 23:14:58 【问题描述】:

可能重复:How should I unit test threaded code?Guidelines for testing multithreaded code or ensuring that code is thread-safe

是否可以“单元测试”一个简单的类是否是线程安全的?

我的具体情况是一个简单的类,它对向量进行子集:给定要保留的向量位置的“白名单”和一个输入向量,它会生成一个输出向量,其中仅包含白名单中位置的值。我想编写一个单元测试(如果可能的话)以确保如果我们将来重构这个类,我们会保持它的线程安全。如果该类不再是线程安全的,则单元测试将失败。我意识到这有点模糊和定义不足。

【问题讨论】:

唯一可以确定的方法是通过一些密集的线程测试来实际运行它,这些测试旨在捕获诸如竞争条件和丢弃值之类的东西。 但它会可靠地工作吗?测试是否只是有时会失败? 你不能通过测试证明一个类是线程安全的。您只能尝试对其进行压力测试,希望如果您有并发错误,它们会出现,但不能保证它们会出现。 How should I unit test threaded code? 和 Guidelines for testing multithreaded code or ensuring that code is thread-safe 的可能重复 针对线程问题进行单元测试的问题在于,您的测试工具实际上总是具有与实际应用程序不同的时序行为(以及 CPU 和内存行为),而线程问题通常对这些事情很敏感。这是因为诸如无死锁和活跃性之类的东西是全局属性,而不是(通常)组件级属性。 【参考方案1】:

这正是Java Pathfinder 的用途。它的学习曲线有点陡峭,但实际上可以使用此工具构建详尽的证明。您构建一个场景并使用 JPF 运行它,然后 JPF 探索所有可能的线程顺序以查找可能的错误。您需要在程序中构建断言以供 JPF 检查。 JPF 在执行期间假定顺序一致性,但您也可以使用 Java Racefinder 插件来证明这一点。

诚然,很难建立一个适当的证明——但这是可能的。如果没有其他办法,JPF 可以用来帮助您根除一些您可能会错过的并发错误。

【讨论】:

【参考方案2】:

线程安全是一个类有或没有的属性。线程安全可能意味着,取决于上下文,没有竞争条件,以特定顺序执行代码或其他任何东西。

测试不能证明没有错误,它只能揭示它们。在我确保多线程代码正确的(不是那么广泛的)经验中,最好的提示可能是保持代码尽可能简单和清晰,并尝试通过检查发现错误。重复运行测试不会有太大帮助。

【讨论】:

以上是关于在Java中测试线程安全[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Java 在多线程环境中测试某些东西 [重复]

我是怎样测试Java类的线程安全性的

Java:测试对“非线程安全”方法的线程访问

java 单例 线程安全 写一个测试类 说明下面单例不是线程安全的

在JAVA中ArrayList如何保证线程安全

简单测试Java线程安全中阻塞同步与非阻塞同步性能