Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从JUnit线程中断信号量?_Java_Multithreading_Junit_Semaphore - Fatal编程技术网

Java 如何从JUnit线程中断信号量?

Java 如何从JUnit线程中断信号量?,java,multithreading,junit,semaphore,Java,Multithreading,Junit,Semaphore,我有一个我想要测试的方法的实现 @Override public void onMessage(final Message message) { try { LOG.fine("waiting on semaphore for " + message); semaphore.acquire(); LOG.fine("semaphore acquired for " + message); listener.onMes

我有一个我想要测试的方法的实现

    @Override
public void onMessage(final Message message) {
    try {
        LOG.fine("waiting on semaphore for " + message);
        semaphore.acquire();
        LOG.fine("semaphore acquired for " + message);
        listener.onMessage(message);
        LOG.fine(message + " processed");
    } catch (final InterruptedException e) {
        throw new RuntimeException(e);
    } finally {
        semaphore.release();
    }
}

但是,我不知道如何从JUnit测试中装配InterruptedException。理论上,我可以添加钩子来终止它,但这会污染代码库,因为代码只用于测试,我希望避免这种情况。

您应该模拟信号量。在我的测试中,您伪造的信号应该抛出InterruptedException,在调用onMessage之前中断当前线程,这将导致acquire方法抛出,即使它不需要阻塞,但我不知道这是否会在所有JRE中发生

另一个选项是为此使用多个线程。 让一个线程调用onMessage,在它的侦听器中,向两个线程发出信号,让它们调用onMessage,然后阻塞,直到线程2完成。 让线程2阻塞,直到线程1锁定信号量。然后它应该中断自身并调用消息。一旦获得预期的运行时异常,它应该向线程1发出停止阻塞的信号

我会使用两个倒计时锁让两个线程通信


如果测试失败,请确保终止两个线程。

请解释一下,当您的方法在semaphore.acquire()处等待时,您想从junit测试调用semaphore.release()?这只是测试JMS消息传递的代码片段,以确保所有消息都在我预期的时间内被发送和处理。完整的源代码在这里:我可以测试它是否工作,但我无法测试信号量会导致中断异常的条件。dbf的意思是,如果acquire失败,您不应该释放信号量。finally块应该位于调用semaphore.acquire()后启动的try块中。不幸的是,该信号量是在类中创建的,不需要公开它使用信号量的事实。因此,如果我按照您的建议做了,那么我将在API中添加一些额外的内容,仅用于测试。1)您需要触发器信号量(内部对象)。这意味着您已经在测试特定于内部/实现的行为。2) 您不必更改api—有很多更改私有变量的技术。3) 改变api进行测试并没有什么错。api的设计应始终考虑测试。只需添加包作用域setSemapthore或extract方法来执行semaphore.acquire和部分模拟。你需要修改一下你的设计,使你的代码可以测试