简体   繁体   English

阻塞队列元素对其他线程不可见,有时导致没有元素检索

[英]Blocking Queue elements are not visible to other thread sometimes causing no elements to retrieve

I am using LinkedBlokingQueue and it is shared between 2 threads. 我正在使用LinkedBlokingQueue ,它在2个线程之间共享。 From the 1st thread constructor I have passed Queue object to 2nd thread. 从第一个线程构造函数,我已经将Queue对象传递给了第二个线程。

I use likedBlockingQueue.put in 1st thread. 我在第一个线程中使用了likedBlockingQueue.put

Second thread uses likedBlockingQueue.size()>0 and likedBlockingQueue.peek() to get the element. 第二个线程使用likedBlockingQueue.size()>0likedBlockingQueue.peek()来获取元素。

The issue is in 1 of my environment sometimes the second thread is giving empty, though I can see the first thread is at blocking call at put (as I have initialized queue size as 1). 问题出在我的环境1中,有时第二个线程为空,尽管我可以看到第一个线程正在阻塞调用(因为我已将队列大小初始化为1)。 This issue is not happening always but only replicating sometimes. 此问题并非总是发生,而有时只是复制。 Couldn't able to understand what causes this issue as per the java documents this Queue seems to be thread safe. 根据Java文档,此Queue似乎是线程安全的,因此无法理解是什么导致了此问题。 Could anyone share any points on this? 谁能在此分享任何观点?

I tried replicating this but only happens few times, other times I could able to get the element from the Queue. 我尝试复制它,但是只发生了几次,其他时候我可以从队列中获取元素。

1 Thread : 1个线程

private final Queue<T> linkedQ = new LinkedBlokingQueue(1);
linkedQ.put(element);

2 Thread : 2个线程

while(condition)
{
    if(this.linkedQ.size>0)
    {
        Object a = this.linkedQ.peek();
        linkedQ.remove();
        break;
    }
}

No error, when I debug when this issue happened, the Q in the second thread showed empty. 没错,当我调试发生此问题时,第二个线程中的Q显示为空。

In this case you should be using neither size() nor peek() nor remove() . 在这种情况下,您既不应使用size()也不使用peek()remove() The LinkedBlockingQueue is a queue that blocks (hence the name). LinkedBlockingQueue是一个阻塞的队列(因此​​得名)。 Both size() and peek() are non-blocking (well, technically they block for a second, but they don't act in a producer-consumer fashion). size()peek()都是非阻塞的(嗯,从技术上讲,它们阻塞了一秒钟,但是它们并不以生产者-消费者的方式起作用)。

You want an operation that tells the current thread "Wait here until an element appears on the queue". 您需要一个告诉当前线程“在这里等待,直到元素出现在队列中”的操作。 Looking at the API, for peek() it reads 查看API,读取的peek()

Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty. 检索但不删除此队列的头部,如果此队列为空,则返回null。

Returning null if the queue is empty explains that no waiting is performed. 如果队列为空,则返回null表示没有等待。 The operation you're looking for is take() . 您要查找的操作是take()

public E take() 公共E take()

Retrieves and removes the head of this queue, waiting if necessary until an element becomes available. 检索并删除此队列的头,如有必要,请等待直到元素可用。

Your usage here would then be: 这样您的用法将是:

while(condition) {
    Object a = linkedQ.take(); // leaving out the interrupted exception for brevities sake
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM