并发的测试并不容易,原因在于并发的不确定性——并发场景下,很多问题无法重现,甚至它还有一个专有的名词,“海森堡错误”。此外,对于Java来说,性能测试经常是比较困难的,这是由于JVM做了太多事,犹如一个黑箱,像垃圾回收,实时编译,提前编译等,对于性能的影响其实很大,要命的事,它们通常不是程序可控的范围,所以需要更加小心。
正确性测试
正确性测试有一部分是串行正确性——即,在串行环境下,我们通常考虑的该程序的种种不变性条件。例如初始容量,各种操作等等。这部分就不展开了,也没有什么特殊的。
阻塞测试
阻塞是并行程序常见的情况,我们通常利用阻塞来减少空循环造成的开销。然而,阻塞并不好测试——如果程序阻塞来,我就收不到任何反馈;如果程序反馈,说明阻塞失败了;假如程序长时间阻塞,那么我又怎么知道下一刻它不会恢复正常?
我们会联想到中断机制,利用中断机制,来确定程序是处于阻塞状态。
void testTakeBlocksWhenEmpty() {
final BoundedBuffer<Integer> bb = new BoundedBuffer<Integer>(10);
Thread taker = new Thread() {
public void run() {
try {
// 空队列获取元素,阻塞
int unused = bb.take();
// 如果执行fail(),则表示阻塞失败
fail(); // if we get here, it's an error
} catch (InterruptedException success) {
}
}
};
try {
taker.start();
// 主线程sleep一小段时间,保证taker
Thread.sleep(LOCKUP_DETECT_TIMEOUT);
// 打断
taker.interrupt();
taker.join(LOCKUP_DETECT_TIMEOUT);
// 如果中断成功,则这里输入false
assertFalse(taker.isAlive());
} catch (Exception unexpected)