1

我在这个question中看到了一段代码,我不明白(很可能是因为这个领域的初学者)。这个问题是关于“一个明显的种族情况,有时生产者会完成,发出信号,消费者工作人员将在消耗队列中的所有东西之前停止。”在这个多线程的java代码中真的存在竞争条件吗?

  1. 在我的理解,“isRunning”将在消费者进行设置后,才生产者决定不在队列中不再添加项目。因此,如果消费者线程将isRunning视为FALSE,然后看到inputQueue为空,那么未来无法再有更多任务添加到队列中。显然,我错了,错过了一些东西,因为没有人回答这个问题说这个问题的场景是不可能的。那么,有人可以解释什么样的事件导致了这种竞争状态?

  2. 事实上,我发现有其他问题。例如,如果多个消费者线程看到生产者正在运行,并且说队列有一个项目,则许多线程可能会进入被阻止的'take'。如果生产商STOPS现在只有一个线程会从'take'中出来,其他线程永远被阻止在'take'上。有趣的是,没有人回答这个问题也指出了这个问题。那么,我对此的理解也可能是错误的!

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

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

回答

1

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

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

而不是

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

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

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

+1

我有同样的想法。我确实检查了关于该问题的“编辑”,看看OP是否改变了问题并修改了操作员。但是,他没有。该运算符总是||。这个问题中没有人质疑这个问题! – brainOverflow 2013-04-21 19:16:39

+0

这可能是因为它没有必要,因为这两个表达式都是错误的,所以解决方案是必需的。一个简单的监督真的。 – didierc 2013-04-21 19:51:57

0

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

至于我,我想创建它汇集两个队列和isRunning可变新的同步的类,从而改变isRunning导致异常在take()从而信令工作结束。

+0

我真的很喜欢@PeterLawrey回应最好的。但那就是我。 – brainOverflow 2013-04-22 17:44:17