0

在不使用休眠的模拟流(因为它们会对中断做出反应)的情况下,如何测试我的应用程序代码的行为以应对 IO 性能非常差的情况?

例如,我想测试一个ConcurrentWrapper具有文件 IO 线程池的实用程序。它将每个操作提交给一个ExecutorService带有invokeAll()超时的操作。我不仅要确认调用ConcurrentWrapper在超时之前退出,而且还要确认它以某种方式使其内部线程ExecutorService终止(以避免泄漏)。

我需要以某种方式模拟内部线程中的慢速 IO,但是以一种忽略中断的方式(就像真正的 IO 一样)。

澄清一下:没有像“睡觉和吞咽InterruptedException”或“睡觉,抓住InterruptedException然后继续睡觉”这样的答案是可以接受的。我想测试我的代码如何处理中断,而这种检测会通过处理它们本身来破坏目的。

4

3 回答 3

1

您可以通过中断坚持睡眠的方式进行睡眠:

long start = System.currentTimeMillis();
long end = start + sleepTime;
for (long now = start; now < end; now = System.currentTimeMillis()) {
    try {
        Thread.sleep(end - now);
    } catch (InterruptedException ignored) {
    }
}
于 2012-06-04T15:34:18.277 回答
0

对于超时测试,您实际上可以设置执行测试的最长时间,在JUnit中您可以包含注释超时:

@Test(timeout=100)
public void method_withTimeout() {
       while(true);
}

对于该方法退出的测试部分,您可以使用Future接口,该接口提供超时以获取结果。

于 2012-06-04T15:38:17.343 回答
0

如果我正确理解您的问题,ReentrantLock 可能会有所帮助。

final ReentrantLock lock = new ReentrantLock();

Callable<Void> c = new Callable<Void>() {
  public void call() {
    lock.lock();

    try {

       if (Thread.currentThread().isInterrupted()) {
         ...
       }
    }
    finally {
      lock.unlock();
    }
  }
}

// Submit to the pool
Future<Void> future = executorService.submit(c);

// you might want to sleep a bit to give the pool a chance
// to pull off the queue.

// Issue a cancel
future.cancel();

// Now release the lock, which should let your
// callable continue onto to the interrupted check.
lock.unlock();

请注意,“lock”方法不会抛出任何 InterruptedException(尽管有一个称为“lockInterruptibly”的方法),如果您查看该类的代码,它不会捕获和吞咽(正如您所说的不会成为你想成为的人)。

于 2012-06-04T19:26:01.353 回答