2012-06-04 31 views
0

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

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

我需要以某种方式模拟内部线程中的缓慢IO,但以某种方式忽略中断(如真正的IO)。

澄清的一点:没有答案,如“睡眠和吞咽InterruptedException”或“休眠,抓InterruptedException并回去睡觉”是可以接受的。我想测试我的代码如何处理中断,而这种工具通过处理它们本身来击败目标。

+0

让它睡了一段指定的时间,如果它早早醒来,回去睡觉? –

+0

所以你想要一个线程阻塞(模拟慢IO),然后抛出一个中断的异常,但继续阻塞(模拟IO继续执行)?这没有多大意义。随着时间的推移,一个方法调用阻塞,返回或抛出异常;它不能做三分之二。你能更清楚你想完成什么吗? –

+0

我在第二段中描述了用例 - 为限制调用持续时间的包装器/帮助器编写测试,不仅验证调用完成,还验证它不会在内部池中泄漏,因为任务仍在运行在后台线程。 –

回答

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) { 
    } 
} 
+0

如果我不够清楚,请查看更新后的问题。我想测试我的代码如何处理中断,所以仪器必须完全忽略它们。无声吞咽不够不引人注目。 –

0

对于超时的测试,实际上你可以把一个最大的时间来执行测试,在JUnit可以包括注释超时:

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

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

+0

这是如何模拟慢IO? –

+0

关于缓慢的IO,一个非最佳的可能性是在发送数据与计算之间替换睡眠。 –

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(); 

注意,“锁定”方法不抛出任何InterruptedException的(虽然有所谓“的lockInterruptibly”应该是一个方法),如果你看一下那个类的代码,它不捕捉和吞食(正如你所说的不会是你想要的)。