0

我遇到的问题类似于单个生产者多消费者问题。除了消费者是“不同的”,我需要一种在购买新商品之前“偷看”新商品的方法(以检查它的用途)。

问题实际上是服务于多个客户端线程的单个服务器线程。客户端将请求信息,然后服务器应回复此客户端

我怎样才能做到这一点?一种可能性是像这样的循环:

while (true) {
    if (q.peek() ... check here ...) {
        // do something
    } else {
        Sleep(...); // prevent taking up too much CPU?
    }
}

但似乎并不理想/对吗?

4

3 回答 3

2

这里有两个选项:

选项 1. 让队列中的一个消费者取出物品并将它们委托给“真正的”消费者。这需要您做很多工作,因为您的主要消费者必须知道哪些“真正的”消费者很忙。此外,如果“真正的”消费者之一比其他消费者占用更多资源,则它有可能在主要消费者等待传递消息时阻塞队列。

更好的解决方案是:

选项 2. 为每种类型的消费者使用一个队列。您的生产者将确定每种消息类型属于哪个队列并将其放入正确的队列中。然后每个消费者将从它感兴趣的队列中拉出。

于 2013-02-26T04:09:57.340 回答
0

您可能需要通过在单个块中同步它们来使以下操作成为原子操作。

// Make sure queue is final. If not, use a final Object monitor.
synchronized(queue) {
    queue.peek
    queue.pool
}

这是为了确保在您的消费者线程发现队列包含正确的目标消息(通过BlockingQueue.peek)后,它可以消费消息(通过BlockingQueue.pool

不过,您的解决方案并不理想。您正在实施一种名为 的技术busy pooling,这会浪费大量 CPU 资源。你没有利用BlockingQueue.pool. BlockingQueue.pool将使您的消费者线程处于等待阶段,直到数据可用。

为了充分利用BlockingQueue.pool,每个消费者线程都应该拥有自己的队列。这样他们就可以只打电话pool而不必执行忙碌peek

于 2013-02-26T04:27:35.713 回答
0

也许最好不要使用 BlockingQueue:

public class Synchronizer {
    Object obj;

    synchronized void put(Object obj) throws InterruptedException {
        this.obj = obj;
        notifyAll();
        while(obj != null) {
            wait();
        }
    }

    synchronized Object take() throws InterruptedException {
        for(;;) {
            wait();
            if (obj instanceof MyObject) {
                notifyAll();
                Object tmp = obj;
                obj = null;
                return tmp;
            }
        }
    }
}

尽管可能存在从 BlockingQueue 消耗的 Synchronzer 版本

于 2013-02-26T04:41:57.827 回答