【发布时间】:2011-01-03 00:41:35
【问题描述】:
我已经实现了一个Pipe 类,它在内部使用BlockingQueue 来存储它接收到的数据。
BlockingQueue会阻塞调用线程有两种情况:
- 调用线程调用
Dequeue(),队列为空。它将阻塞线程,直到有要检索的项目。 - 调用线程调用
Enqueue(),队列已满。它将阻塞线程,直到有空间再次插入数据。
我最初的想法是,不是让Pipe 类实例化BlockingQueue,而是通过构造函数注入将IQueue 的实例传递给它。这样,在测试时,我会将NonBlockingQueue 的实例传递给它,因此我不必为线程问题而烦恼(当我为Pipe 类和其他类进行单元测试时)使用Pipes 的类我只想将东西添加到队列中,而不必考虑它们是否已经满了等等)。
问题在于,在执行此操作时,我实际上使我的 Pipe 以两种完全不同的方式运行,具体取决于我传递给它的 IQueue 实例的类型:
在
BlockingQueue中,如果队列是 为空,您尝试检索 来自它的东西,它会阻塞直到 它得到了一些东西。在一个NonBlockingQueue它会呕吐 一个例外。在
BlockingQueue中,如果队列已满并且您尝试添加某些内容,它将等到有人将元素出列并且再次有空间。NonBlockingQueue版本要么抛出FullQueueException,要么允许“无限”数量的元素。
也就是说,没有“单一合同”。我认为这种做法肯定是错误的。
什么是更合适的方法?
编辑米奇:
这用于实现 Pipe&Filter 系统:每个 Filter 都有一个输入和输出管道。 然后每个过滤器都使用以下形式的代码实现
char c;
while ((c = inputPipe.ReadChar()) != STREAM_TERMINATOR) {
//I don't have to care
//if right now there is any data. I know that if there isn't,
//the thread will block and this will continue after there is some.
...do processing
outputPipe.WriteChar(something);
}
outputPipe.WriteChar(STREAM_TERMINATOR);
所以我想是的,阻塞管道/队列是我想要的行为。
【问题讨论】:
标签: c# java multithreading unit-testing testing