如何在Java中有效地测试(单元/集成)并发代码?

时间:2009-10-22 18:30:33

标签: java testing multithreading

我已经在SO上发布了this帖子,但它仍然存在问题,至少对Java而言。对于任何应用程序(我正在测试此用例的Web应用程序)来说,这应该是一个紧迫的问题,这是多线程的。你们是如何以允许线程交错的方式处理它的 - 本质上意味着测试随机线程行为。

6 个答案:

答案 0 :(得分:9)

我认为这本来就很困难,因为你正在寻找证明某个(可能)非决定性系统中缺少某些东西的东西。话虽如此,总是值得编写可重复的测试来强调你的多线程组件。如果出现问题,您可能无法重复,但您可以通过检查找到错误。因此,请确保您的测试详细记录了相关的异常(可能还有输入参数等)。

还值得运行静态代码分析器。这些将获取(除其他外)变量的不一致同步,并立即突出显示需要关注的区域。 FindBugs就是这样一种工具。

答案 1 :(得分:3)

我通常会在单元测试中产生大量(如100个)线程并将它们发送出去,以期达到竞争条件:)。可悲的是,这不是很确定。您可以通过在线程敏感区域中使用调试行来提高您的可能性,这些调试行会导致活动线程在X毫秒内休眠。此策略允许您在其他线程可以交错的情况下留下间隙窗口。这些行仅在单元测试期间有效(使用仅在设置调试标志时激活的方面或硬代码行)。

证明消极是不可能的。你不能真正证明你没有并发问题。您所能做的就是设置测试以尽可能彻底地进行测试。

答案 2 :(得分:2)

我建议你得到Java Concurrency in Practice - 它不仅告诉你如何避免竞争条件,还有一节关于测试并发性。

还有可用于Java的并发静态分析工具 - 不幸的是,虽然我知道它们在那里,但我还没有能够对它们进行评估。

答案 3 :(得分:0)

测试这个的一个好方法是确保您可以访问多CPU机器,然后运行您的测试很长一段时间/尽可能多的迭代。例如,如果您有一个多线程生成器使用者算法,请使用大小合适的列表填充队列,并使用2x尽可能多的线程。这至少应该让您有机会更频繁地遇到竞争条件或同步问题。然后在每日构建中运行此测试。

答案 4 :(得分:0)

我对此的回答是避免在明智地使用智能设计和现有技术的情况下创造竞争条件。例如,如果您的MT应用程序使用自包含的工作项,则可以在应用程序中嵌入JMS代理,以用作线程之间的通信机制。与可能受竞争条件影响的系统资源类似,不要使这些部分成为多线程。如果你有文件,你需要编写一个线程负责使用通过JMS子系统传递的信息来编写它们。

最终,没有数字方式来测试MT代码,以确保它不会受到竞争条件的影响。

答案 5 :(得分:-1)

不应测试由于非确定性线程问题而可能失败的代码。相反,它应该被删除,并替换为可能的东西。

大多数情况下,只需将所有内容都设置为单线程即可完成此操作 - 只需要一小部分应用程序需要在进程中的先发制人调度提供的轻微可扩展性提升。或者,您可以设置线程体系结构,其中使用操作系统,编译器或第三方工具来提供无法确保无法执行操作的硬保证。