Gee*_*eek 3 java random concurrency multithreading java.util.concurrent
来自Java Concurrency in Practice,第12.1章测试正确性,特别是12.1.3 测试安全性(作者希望设置用于测试Bounded Buffer类的数据竞争安全性的测试用例)
为了确保您的测试实际测试您的想法,重要的是校验和本身不能被编译器猜测.使用连续的整数作为测试数据是一个坏主意,因为结果总是相同的,智能编译器可以想象它只是预先计算它.
为了避免这个问题,测试数据应该是随机生成的,但许多其他有效的测试都会受到随机数生成器(RNG)选择不当的影响.随机数生成可以在类和时序工件之间创建耦合,因为大多数随机数生成器类是线程安全的,因此引入了额外的同步.给每个线程自己的RNG允许使用非线程安全的RNG.
我不明白作者反对使用随机数生成器生成测试输入的观点.特别是行随机数生成可以创建类之间的耦合,并且我不清楚时序伪像.
随机数生成可以在类之间创建耦合,并且我不清楚时序伪像.
考虑到下一句话,这一点就更清楚了:
因为大多数随机数生成器类是线程安全的,因此引入了额外的同步
内存同步可能会改变程序的时间.如果你研究一下Random,你可以看到它使用了一个AtomicInteger封面,所以使用它将导致读写内存障碍,作为生成测试数据的一部分,这可能会改变其他线程看到数据的方式以及整个应用程序的时间.
他指的是哪些类和时序工件?
任何使用线程并依赖于内存同步的类都可能会受到影响.基本上他们调用的所有线程和类.
RNG可以创造什么样的联轴器?
正如蜥蜴@Bill评论的那样,本书说通过使用RNG,程序的时间依赖于RNG同步或受其影响.
这里真正的教训是,如果可能的话,您注入程序的测试数据不应该改变程序的时间.它通常很难并且可能是不可能的,但目标是在测试中尽可能地模拟应用程序行为(时间,输入,输出......).
就解决方案而言,您可以使用另一个未同步的简单随机算法.您还可以生成一个类,该类预先存储10000个随机数(或者您需要的多个),然后在没有同步的情况下将它们分发出去.但是通过在测试中使用类进行内存同步,您正在改变程序的时间.