多个生产者消费者 java,Java并发:多生产者一个消费者

I have a situation where different threads populate a queue (producers) and one consumer retrieve element from this queue. My problem is that when one of these elements are retrieved from the queue some is missed (missing signal?). The producers code is:

class Producer implements Runnable {

private Consumer consumer;

Producer(Consumer consumer) { this.consumer = consumer; }

@Override

public void run() {

consumer.send("message");

}

}

and they are created and run with:

ExecutorService executor = Executors.newSingleThreadExecutor();

for (int i = 0; i < 20; i++) {

executor.execute(new Producer(consumer));

}

Consumer code is:

class Consumer implements Runnable {

private Queue queue = new ConcurrentLinkedQueue();

void send(String message) {

synchronized (queue) {

queue.add(message);

System.out.println("SIZE: " + queue.size());

queue.notify();

}

}

@Override

public void run() {

int counter = 0;

synchronized (queue) {

while(true) {

try {

System.out.println("SLEEP");

queue.wait(10);

} catch (InterruptedException e) {

Thread.interrupted();

}

System.out.println(counter);

if (!queue.isEmpty()) {

queue.poll();

counter++;

}

}

}

}

}

When the code is run I get sometimes 20 elements added and 20 retrieved, but in other cases the elements retrieved are less than 20. Any idea how to fix that?

解决方案

I'd suggest you use a BlockingQueue instead of a Queue. A LinkedBlockingDeque might be a good candidate for you.

Your code would look like this:

void send(String message) {

synchronized (queue) {

queue.put(message);

System.out.println("SIZE: " + queue.size());

}

}

and then you'd need to just

queue.take()

on your consumer thread

The idea is that .take() will block until an item is available in the queue and then return exactly one (which is where I think your implementation suffers: missing notification while polling). .put() is responsible for doing all the notifications for you. No wait/notifies needed.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值