Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程安全单元测试_Java_Multithreading_Unit Testing_Thread Safety - Fatal编程技术网

Java 线程安全单元测试

Java 线程安全单元测试,java,multithreading,unit-testing,thread-safety,Java,Multithreading,Unit Testing,Thread Safety,从我所读到的内容来看,单元测试线程安全没有“好的”通用解决方案。但我想为一个具体问题找到一个好的解决方案 让我们考虑这个(哑)动态列表实现。add方法显然不是线程安全的。既然它是线程安全的(让我们考虑,我们将不执行任何删除< /代码>方法并保持它为哑),那么一个单元如何测试该代码,以显示它实际上不是线程安全的,并显示线程安全修复确实有效(或似乎有效)?< /P> 您可以尝试通过在测试该方法的线程中放置休眠来模拟竞争条件。但显然,这不是一个100%可靠的测试。我的建议是,只要事先知道代码将同时被访

从我所读到的内容来看,单元测试线程安全没有“好的”通用解决方案。但我想为一个具体问题找到一个好的解决方案

让我们考虑这个(哑)动态列表实现。

add
方法显然不是线程安全的。既然它是线程安全的(让我们考虑,我们将不执行任何<代码>删除< /代码>方法并保持它为哑),那么一个单元如何测试该代码,以显示它实际上不是线程安全的,并显示线程安全修复确实有效(或似乎有效)?< /P>
您可以尝试通过在测试该方法的线程中放置休眠来模拟竞争条件。但显然,这不是一个100%可靠的测试。我的建议是,只要事先知道代码将同时被访问,就可以使代码线程安全。否则,您将为我们钟爱的同步错误打开空间…

您可以尝试一些实用程序,如jcstress或threadweaver,它们将为您的实现插入字节码并生成压力测试。

在测试过程中,您将面临以下两个问题

  • 根据所使用的硬件或jvm,程序的行为可能会有所不同
  • bug只发生在非常特定的线程和计时星座中
  • 要解决第2点,您可以使用。它基本上测试断言列表 负载不足。我认为这可能是适合您的用例的正确解决方案, 开发新的并发集合

    要解决第1点,可以使用。它是一种检查程序中所有访问字段是否运行的工具 可以根据java内存模型进行订购。 这可以确保程序的顺序不依赖于硬件或jvm

    因此,如果您的用例是开发一个新的并发集合,我会与 然后在多核机器上进行测试


    (我有偏见,我开发)

    你不能保证两个线程通过<代码> Addio>代码>方法,或者当这两个线程可能被抢占时,因此你不能编写一个一致的可能的复制品,因为我试图在一个例子中得到答案,所以我不认为它是一个复制品。但实际上,在任何情况下都无法正确地进行单元测试线程安全性。。。证明多线程代码按预期工作的唯一方法是测试各个线程执行的“操作”(即共享内存读写)的所有可能序列化。这对于小型算法和少量线程来说是可行的,但据我所知,这仍然是一个研究主题:我没有听说过任何工具可以帮助枚举或强制Java字节码的不同序列化。您可以使用类似于库的等待来模拟特定的排序,然后让线程对其进行适当的处理。
    public class ArrayList {
    
        private int capacity = 2;
        private Object[] content = new Object[capacity];
        private int size;
    
        public void add(Object object) {
            if (size == capacity) {
                ensureCapacity();
            }
            content[size++] = object;
        }
    
        public Object get(int index) {
            if (index >= size) {
                throw new IndexOutOfBoundsException();
            }
            return content[index];
        }
    
        private void ensureCapacity() {
            int extendedCapacity = capacity * 2;
            Object[] extended = new Object[extendedCapacity];
    
            System.arraycopy(content, 0, extended, 0, size);
    
            this.capacity = extendedCapacity;
            this.content = extended;
        }
    }