使用ConTest进行多线程单元测试 - 编程入门网
e final Object lock = new Object();
public void enqueue(String str) {
synchronized (lock) {
queue.addLast(str);
lock.notifyAll();
}
}
public void work() {
String current;
synchronized(lock) {
if (queue.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
assert (false);
}
}
current = queue.removeFirst();
}
System.out.println(current);
}
public static void main(String[] args) {
final PrintQueue pq = new PrintQueue();
Thread producer1 = new Thread() {
public void run() {
pq.enqueue("anemone");
pq.enqueue("tulip");
pq.enqueue("cyclamen");
}
};
Thread producer2 = new Thread() {
public void run() {
pq.enqueue("iris");
pq.enqueue("narcissus");
pq.enqueue("daffodil");
}
};
Thread consumer1 = new Thread() {
public void run() {
pq.work();
pq.work();
pq.work();
pq.work();
}
};
Thread consumer2 = new Thread() {
public void run() {
pq.work();
pq.work();
}
};
producer1.start();
consumer1.start();
consumer2.start();
producer2.start();
}
}
运行测试以后,所有看起来都正常。作为类的开发者,您很可能感到非常满 意:此测试看起来很有用(两个 producer、两个 consumer 和它们之间的能试 验 wait 的有趣顺序),并且它能正确地运行。 但是这里有一个我们提到的 bug。您看到了吗?如果没有看到,先等一下; 我们将很快捕获它。 使用ConTest进行多线程单元测试(4)时间:2010-12-08 IBM Yarden Nir-Buchbinde并行程序设计中的确定性 为什么这两个示例单元测试不能测试出并行 bug?虽然原则上线程调度程序 可以 在运行的中间切换线程并以不同的顺序运行它们,但是它往往 不进行切换 。因为在单元测试中的并行任务通常很小同时也很少,在调度程序切换线程之前 它们通常一直运行到结束,除非强迫它(也就是通过 wait())。并且当它确实 执行了线程切换时,每次运行程序时它往往都在同一个位置进行切换。 像我们前面所说的一样,问题在于程序是太确定的:您只是在很多交错情况 的一种交错(不同线程中命令的相对顺序)中结束了测试。更多的交错在什么时 候试验?当有更多的并行任务以及在并行类和协议之间有更复杂的相互影响时, 也就是当您运行系统测试和功能测试时 -- 或当整个产品在用户的站点运行时, 这些地方将是暴露出 bug 的地方。 使用 ConTest 进行单元测试 当进行单元测试时需要 JVM 具有低的确定性,同时是更“模糊的”。这就是 要用到 ConTest 的地方。如果使用 ConTest 运行几次 清单 2 的 NakedNamePrinter, 将得到各种结果,如清单 4 所示: 清单 4. 使用 ConTest 的无修饰的 NamePrinter
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |