在此多线程Java代码中是否真的存在竞争条件? [英] Is there really a race condition in this multi-threaded java code?

查看:142
本文介绍了在此多线程Java代码中是否真的存在竞争条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个问题中,我看到了一段代码,我无法理解(很可能是因为事实是该领域的初学者).这个问题是关于一种明显的竞争条件,在这种竞争条件下,生产者有时会完成信号并发出信号,而ConsumerWorkers会在消耗队列中的所有内容之前停止运行."

I saw a snippet of code in this question which I could not understand (most probably due to the fact am a beginner in this area). The question talks about "an obvious race condition where sometimes the producer will finish, signal it, and the ConsumerWorkers will stop BEFORE consuming everything in the queue."

  1. 据我所知,只有在生产者决定不再在队列中添加项目之后,才会在消费者上设置"isRunning".因此,如果使用者线程看到isRunning为FALSE,然后看到inputQueue为空,那么将来就不可能再有其他任何东西添加到队列中了. 显然,我错了,缺少了一些东西,因为没有人回答这个问题说不可能解决这个问题.那么,有人可以解释一下导致此竞赛条件的事件顺序是什么吗?

  1. In my understanding, "isRunning" will be set on the consumers only after the producer decides not to add anymore items in the queue. So, if a consumer thread sees isRunning as FALSE AND then sees inputQueue is empty, then there is NO possibility of anything more getting added into the queue in the future. Obviosuly, I am wrong and missing something, as no one who responded to that question said the scenario of the question is impossible. So, Can someone pls explain what sequence of events causes this race condition ?

事实上,我发现其他问题.例如,如果多个使用者线程看到生产者正在运行,并且说队列中只有一个项目,则许多线程可以进入被阻止的接管".如果生产者现在停止,而接取"中会有一个线程出来, 其他线程永远被阻塞.有趣的是,没有人回答这个问题.因此,我对此的理解也可能是错误的?!

In fact, I see a problem with something else. For ex, if multiple consumer threads saw that the producer isRunning, and say the queue had ONE item, many threads could enter the blocked 'take'. If the producer STOPS now, while one thread would come out of the 'take', the other threads are blocked on the 'take' forever. Interestingly, no one who answered the question pointed out this problem as well. So, my understanding of this is also probably faulty ?!

我不想在该问题中添加评论,因为这是一个老问题,我的疑问可能永远也不会得到回答! 我正在此处复制/放置该问题的代码,以供快速参考.

I didnt want to add this as a comment there in that question, as it is an old question and my doubt may never get answered ! I am copy/placing the code from that question here for quick reference.

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

推荐答案

我认为原始问题的OP可能意味着

I think OP of the original question probably meant

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

而不是

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

前者显然产生了原始张贴者(*)所描述的问题,而后者确实确实存在了您在第二点中所描述的问题.一个简单的疏忽,但是现在我们可以注意到这两种方法都是不正确的.

The former clearly produces the issue described by the original poster (*), while the later does indeed have the problem you described in your second point. A simple oversight there, but now we can note that both approaches are incorrect.

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

这篇关于在此多线程Java代码中是否真的存在竞争条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆