Java 生产者/消费者使用信号量。消费者得到的是尾部,而不是队列的头部
正如标题所示,这是一个使用信号量的生产者/消费者实现 没有死锁问题,但似乎每当消费者想要删除队列中的下一个项目时,它总是尾部 伪代码:Java 生产者/消费者使用信号量。消费者得到的是尾部,而不是队列的头部,java,multithreading,queue,producer-consumer,Java,Multithreading,Queue,Producer Consumer,正如标题所示,这是一个使用信号量的生产者/消费者实现 没有死锁问题,但似乎每当消费者想要删除队列中的下一个项目时,它总是尾部 伪代码: class Consumer { while (!q.isEmpty() || !dataRead()) { empty.acquire(); mutex.acquire(); queue.remove(); mutex.release(); full.release();
class Consumer {
while (!q.isEmpty() || !dataRead())
{
empty.acquire();
mutex.acquire();
queue.remove();
mutex.release();
full.release();
}
synchronized (caller)
{
caller.dataWritten = true;
caller.notify();
}
}
class Producer {
for (int i=0; i < 100; i++)
{
full.acquire();
mutex.acquire();
queue.add(i);
mutex.release();
empty.release();
}
...also notify Consumer that we're done...
}
class MainThread {
...
new Thread(new Producer(args)).start();
new Thread(new Consumer(args)).start();
synchronized (this) {
while (!dataWritten())
wait();
...
}
输出如下所示:
已生成项0…值为0。
第1项产生……价值1。
项目0已消耗…值1。
项目1已消耗…值1。
显然,当我移除头部时,我希望移除的顺序与FIFO相同
我正在使用ConcurrentLinkedQueue实现,但已经尝试了许多其他实现,如LinkedList、BlockingQueue实现等
此外,我还尝试在队列对象上进行同步,并在ditch工作中使变量变为volatile,但这并没有产生任何影响
我认为这与对队列的陈旧引用有关,但是已经没有办法尝试了
编辑:输出的错误在于,当使用项0时,它应该使用值0,而不是1,因为这是为项0生成的值
我似乎无法用最少的代码复制
看起来,如果数据来自一个迭代器,该迭代器只需花费少量的时间来读取信息,那么输出就像我的示例中那样是关闭的,但是如果我只是插入一些常量值,那么输出是正确的。既然只有一个制作人,为什么会有不同呢?我不确定我是否正确解释了您程序的输出。我假设项目x指的是在生产者的for循环中递增的整数。如何设置值字段的值
由于您首先将项目0添加到队列中,并且项目0是您第一次使用的项目,因此队列的行为在我看来似乎是正确的。为什么要给我们PSEDOO代码?给我们一个相反的答案。为什么在消费者中你得到的是空的,但释放的是满的?此外,如果您使用的是ConcurrentLinkedQueue,那么为什么要使用信号量?很可能代码中存在错误,但如果没有我们可以运行的自包含示例,则无法说出位置。@Duncan/Peter我将发布到MCVE的链接@如果你需要一个关于信号量如何工作的参考,你可以在维基百科上查看基本信号量的使用。empty.acquire检查缓冲区中是否有空间,full.release让生产者知道有空间…等等。因此,为了验证,在保证互斥的情况下跨多个线程使用任何队列实现没有明显的错误?输出表示消耗的第一个项的值为1,而实际情况并非如此。项0的值为0。