测试多线程 Java 接缝是不可能的。 错误取决于特定的时间,有时甚至取决于特定的处理器类型或 JVM。 但是 Java 有一个规范可以让我们测试多线程软件:Java 内存模型。
Java 内存模型使我们能够执行多线程程序的所有线程交错,只要该程序是无数据竞争的。 它定义了自动检查程序是否包含数据竞争的规则。 所以我们可以使用两步法进行测试:第一步,我们执行所有线程交错。 在第二步中,我们检查测试是否包含数据竞争。
什么是Java内存模型?
Java内存模型是一种规范,它定义了当多个线程读写相同的内存位置时会发生什么。
Java内存模型以下列方式回答了这个问题:
如果一个程序没有数据竞争,那么该程序的所有执行看起来都是顺序一致的。
顺序一致性意味着多线程程序的运行是不同线程的源代码语句的特定交错。因此,要执行一个顺序一致的程序,我们可以使用以下算法:选择一个线程,并执行该线程的当前语句。重复此操作,直到所有线程都被终止。
但是Java程序只有在没有数据竞争时才是顺序一致的。当一个程序包含一个读和一个写或两个对同一存储位置的写,而这些写不是按照所谓的发生前顺序排序时,该程序就包含了数据竞争。像从volatile字段读取和写入这样的同步操作会在多个线程之间生成一个顺序,即先发生顺序。例如,对一个volatile变量的写操作发生在所有后续的volatile读操作之前。如果所有的内存访问都可以通过这种先发生后关系来排序,那么我们的程序就是无数据竞争的。
Java内存模型的顺序一致性的较弱形式的优势在于,它允许JVM对生成的机器代码进行优化。这使得在处理器中进行缓存成为可能。这种较弱形式的顺序一致性意味着,当我们想要测试所有线程交错时,我们只需要考虑同步动作。
Java内存模型如何支持多线程Java的测试?
测试时,我们只需要考虑导致不同发生前顺序的线程交错。因此,我们计算测试运行的同步操作可以创建的所有订单。对于每个订单,我们执行一次线程交错,从而得到这个订单。
在我们执行了所有这些线程交错之后,我们需要检查测试是否没有数据竞争。因此,我们检查每个多线程内存访问是否可以根据发生前的顺序进行排序。
Java内存模型保证所有无数据竞争的程序顺序一致。这允许我们用两步的方法测试多线程程序。第一步,我们执行所有线程交错,第二步,我们检查数据竞争。这允许我们以系统的、可重复的方式测试多线程Java。
热门跟贴