java BlockingQueue没有阻塞窥视?

2022-09-01 05:26:13

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

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

但是,由于我不知道我是否能够成功处理对象,因此我只想peek()而不删除该对象。仅当我能够成功处理该对象时,我才想删除该对象。

所以,我想要一个阻塞peek()函数。目前,peek() 只是返回队列为空,如 javadocs 所示。

我错过了什么吗?有没有另一种方法可以实现此功能?

编辑:

关于我是否只是使用线程安全队列并偷看和睡觉的任何想法?

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
    }
}

请注意,我只有一个使用者线程和一个(单独的)生产者线程。我想这不如使用BlocklingQueue有效...任何意见表示赞赏。


答案 1

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

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


答案 2

但是,由于我不知道我是否能够成功处理对象,因此我只想peek()而不删除该对象。仅当我能够成功处理该对象时,我才想删除该对象。

通常,它不是线程安全的。如果在您确定该对象可以成功处理之后,但在您删除它之前,另一个线程获取该对象,该怎么办?peek()take()


推荐