java BlockingQueue 没有阻塞窥视?

2022-01-21 00:00:00 queue peek java blockingqueue

我有一个阻塞的对象队列.

I have a blocking queue of objects.

我想写一个线程阻塞直到队列中有一个对象.类似于 BlockingQueue.take() 提供的功能.

I want to write a thread that blocks till there is a object on the queue. Similar to the functionality provided by BlockingQueue.take().

但是,由于我不知道我是否能够成功处理该对象,所以我只想 peek() 而不是删除该对象.只有当我能够成功处理它时,我才想删除它.

However, since I do not know if I will be able to process the object successfully, I want to just peek() and not remove the object. I want to remove the object only if I am able to process it successfully.

所以,我想要一个阻塞 peek() 函数.目前,根据 javadocs,如果队列为空,peek() 只会返回.

So, I would like a blocking peek() function. Currently, peek() just returns if the queue is empty as per the javadocs.

我错过了什么吗?还有其他方法可以实现此功能吗?

Am I missing something? Is there another way to achieve this functionality?

如果我只是使用线程安全队列并偷看和睡觉,有什么想法吗?

Any thoughts on if I just used a thread safe queue and peeked and slept instead?

public void run() {
    while (!exit) {
        while (queue.size() != 0) {
            Object o =  queue.peek();
            if (o != null) {
                if (consume(o) == true) {
                    queue.remove();
                } else {
                    Thread.sleep(10000); //need to backoff (60s) and try again
                }
            }
        }
        Thread.sleep(1000); //wait 1s for object on queue
    }
}

请注意,我只有一个消费者线程和一个(单独的)生产者线程.我想这不如使用 BlockingQueue 高效...任何评论表示赞赏.

Note that I only have one consumer thread and one (separate) producer thread. I guess this isn't as efficient as using a BlockingQueue... Any comments appreciated.

推荐答案

你可以使用 LinkedBlockingDeque 并从队列中物理移除项目(使用 takeLast())但在 队列末尾再次替换它 如果使用 putLast(E e) 处理失败.同时,您的生产者"将使用 putFirst(E e) 将元素添加到队列的 front.

You could use a LinkedBlockingDeque and physically remove the item from the queue (using takeLast()) but replace it again at the end of the queue if processing fails using putLast(E e). Meanwhile your "producers" would add elements to the front of the queue using putFirst(E e).

您始终可以将此行为封装在您自己的 Queue 实现中,并提供一个执行 takeLast()blockingPeek() 方法,然后是 putLast() 在底层 LinkedBlockingDeque 的幕后.因此,从调用客户端的角度来看,该元素永远不会从您的队列中删除.

You could always encapsulate this behaviour within your own Queue implementation and provide a blockingPeek() method that performs takeLast() followed by putLast() behind the scenes on the underlying LinkedBlockingDeque. Hence from the calling client's perspective the element is never removed from your queue.

相关文章