【发布时间】:2016-12-21 23:02:55
【问题描述】:
最近,我正在编写一段涉及同步的代码,并在努力研究如何对其进行测试。为了解决这个问题,我们可以考虑为 CountDownLatch 编写单元测试:
CountDownLatch l = new CountDownLatch(1);
new Thread() {
@Override
void run() {
l.await();
System.out.println("good!");
}
}.start();
Thread.sleep(1000); // wait for thread to run
if (the thread is alive)
l.countDown();
else
System.out.println("bad!");
所以问题是,不能保证sleep 1 秒在所有机器的所有情况下都足够了。所以我的目标是消除这种在测试同步时期望某种状态的睡眠代码,但很快就会意识到它开始变成停止问题。
我目前的解决方案是查询线程的状态:
Thread t = ...
t.start();
if (t.getState() == Thread.State.WAITING) {
l.countDown();
assert(t.getState() == Thread.State.RUNNABLE); // or running or terminated
}
我的问题是:
- 这行得通吗?即此时线程的状态是否会自动地切换,在这种情况下,倒计时锁存器会达到唤醒条件吗?(文档没有说明状态的更改时间)李>
- 您有更好的建议吗?
【问题讨论】:
-
不测试线程状态,测试行为。我不知道你的代码试图做什么,所以我不能告诉你如何测试它。
-
@ИгорьДобровольський 不,我更多的是测试同步机制。
-
通过考虑可能的情况并为它们编写测试。 FWIW,我通常通过将
Runnables/Callables放在单独的单线程ExecutorServices上来测试这类事情,然后让我的单元测试等待它们完成(使用shutdown()和@987654330 @),如果他们没有在几百毫秒内完成,则超时。 Java 8ListenableFutures可能有更好的方法。 -
这种单元测试的目的是什么?当有同步的代码块并且第二个线程会等到第一个线程完成时,您不信任 Java?还是什么?
标签: java multithreading