java - 潜在并发问题的单元测试

标签 java multithreading unit-testing concurrency thread-safety

我最近与我的一位同事(我非常尊重他)就测试某些代码是否线程安全的理论上的可能性进行了一场小型竞赛。

让我们假设我们有一些“黑盒”类 FooUnknown取自第三方库,因此我们无法访问其原始源代码。此外,它可能在内部使用了一些本地方法(如果这是一个问题)。

我们能否编写这样一个单元测试来告诉我们此类的使用(例如,它的实例在多个线程之间共享)是否是 100% 线程安全的?

我的结论是,不可能。对我来说,这是显而易见和直接的:尽管可以编写一段代码,这将导致一些可以检测到的并发问题。但是没有这样的结果并不能保证根本没有并发问题。

而且我相信,这个问题不是太宽泛。可以肯定地说,我们有一个类 some.FooUnknown我们想按以下方式使用它:

@ApplicationScoped
public class FooService {
    private some.FooUnkown foo = new some.FooUnknown();

    public void someStuff() {
        // ...
        String result = foo.doSomeStuff();
        // ...
    }
}

如何测试它以确保它是线程安全的,我们不需要将它包装到 ThreadLocal<FooUnknown> 中例如?

最佳答案

抛开一切实际原因,这也是为什么理论上很难实现一套完整的并发安全测试:

假设有n 个线程在同一个数据结构上运行。然后任何线程 i 对该数据结构有一系列 Si 原子操作,其中每个序列可能有不同的长度。现在,您需要确保在理想环境中,您的测试涵盖了通过这些操作跨所有线程的每个可能的迭代序列。即使对于相对较小的操作序列并且只有 2 个线程,这个数字也会增长得相当快。

但现在困难的部分是将这些发现转化为一台真正的计算机。鉴于 jvms 的实现方式和 java 内存模型的自由度,识别此类原子操作本身就是一项复杂的任务。然后还有os控制的线程调度。因此,您通常无法控制在数据结构上发生的实际操作顺序。

关于java - 潜在并发问题的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47680844/

相关文章:

node.js - 启动后分离一个 spawn 子进程

c++ - QT从主窗口更新工作线程的变量

objective-c - 加载用于单元测试的测试图像

c# - Nunit - TestContext.CurrentContext.Test 不工作

java - Spring bean 创建但未 Autowiring

java - Java 中的撒克逊语 : XSLT Code Reuse

java - 在android中请求最近的城市

java - 如何在运行时启用/禁用上下文菜单项

python - 如何在后台运行无限循环并停止它?

java - Maven Surefire 适当使用Exclude