是否真的有这个多线程Java代码中的竞争条件?(Is there really a race con

2019-09-29 12:53发布

我看到的代码片段在这个问题 ,我无法理解(最可能是由于我在这方面的初学者)。 这个问题谈到“一个明显的竞争条件,其中有时制片人将完成,它的信号,并ConsumerWorkers将停止之前在队列中消耗的一切。”

  1. 在我的理解,“isRunning”将在消费者设置后,方可生产商决定不在队列中不再添加项目。 所以,如果一个消费者线程看到isRunning为false,然后看到inputQueue是空的,然后有更多的获取添加到在未来的队列就都没有可能。 Obviosuly,我错了,失去了一些东西,因为没有人谁回答这个问题说问题的情况下是不可能的。 那么,能不能有人请解释什么事件序列导致这种竞争情况?

  2. 事实上,我看到别的一个问题。 对于恩,如果多个消费者线程看到生产者isRunning,并说出了排队一个项目,多个线程可以进入封锁“接受”。 如果制片人现在结束了,当一个线程将出来的“花”,另一个线程被阻塞在“拿”永远。 有趣的是,没有谁回答提问时指出这个问题为好。 所以,我的这种理解也可能有问题?!

我没有想在这个问题有其添加为评论,因为这是一个老问题,我怀疑可能永远不会得到回答! 我复制/配股代码从这个问题在这里为快速参考。

public class ConsumerWorker implements Runnable{

private BlockingQueue<Produced> inputQueue;
private volatile boolean isRunning = true;

public ConsumerWorker(BlockingQueue<Produced> inputQueue) {
    this.inputQueue = inputQueue;
}

@Override
public void run() {
    //worker loop keeps taking en element from the queue as long as the producer is still running or as 
    //long as the queue is not empty:
    while(isRunning || !inputQueue.isEmpty()) {
        System.out.println("Consumer "+Thread.currentThread().getName()+" START");
        try {
            Object queueElement = inputQueue.take();
            //process queueElement
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//this is used to signal from the main thread that he producer has finished adding stuff to the queue
public void setRunning(boolean isRunning) {
    this.isRunning = isRunning;
}

Answer 1:

我认为原来的问题的OP大概意思

while(isRunning && !inputQueue.isEmpty()) 

而不是

while(isRunning || !inputQueue.isEmpty())

前者显然产生由原始的海报(*)中描述的问题,而后者确实有你在你的第二点所述的问题。 一个简单的监督那里,但现在我们可以注意到,这两种方法是不正确的。

(*),并以某种方式假定队列永远不会空。



Answer 2:

你是在这两个问题是正确的。 是&&是正确的, || 不是。 至于第二个问题,答案是使用poison pill或超时,两种方式解决该问题。

至于我,我想创建它汇集两个队列和新的同步类isRunning变量,以便改变isRunning引起一个异常take()因而信令工作结束。



文章来源: Is there really a race condition in this multi-threaded java code?