我试图与几个生产者和消费者一起实现生产者-消费者模式。
我尝试做
CompletableFuture future = CompletableFuture.runAsync(() -> producer.run(), producerService)
.thenRunAsync(() -> consumer.run(), consumerService);
其中producer.run()
做某事并返回String
,但这不是必需的,consumer.run()
做这样的事
while (!queue.isEmpty()) {
try {
message = queue.poll();
if (message == null || !message.equals(thread)) {
queue.offer(message);
Thread.sleep(1000);
continue;
}
doWork(message);
} catch (InterruptedException e) {
e.printStackTrace();
我的Thread
的名称等于1或2的名称,如果consumerService
中有3个线程,则名称等于3。
message
是我得到的随机数
String.valueOf(1 + new Random().nextInt(2))
用于2个线程。
所以,我的问题是
我该怎么办,而不是thenRunAsync()
,或者我的使用者可以更改线程以从队列中提取message
的其他方式?
它需要生产者生成一个数字列表,例如1,2,1,1,2,1,1,1和消费者与线程,其名称为1,从队列消息中获得数字为1的线程,但名称为2等于2。
我无法完成所有消息,然后执行CompletableFuture.allOf()
,因为如果我要执行约1_000_000个任务,则必须等待它生成,然后再调用我的consumers
答案 0 :(得分:2)
CompletableFuture.run *方法用于使用线程池运行多个短期任务。您的任务不是短命的,它们正在队列中循环并处理多个值。结果,它们占用了线程池中的线程,并且线程池的大小减小,这可能导致线程饥饿(一种死锁)。 因此,您不应使用CompletableFuture.run *方法。改用显式的线程创建。
然后,确保生产者将消息与queue.put()或queue.offer()放入队列,而使用者将消息与queue.get()或queue.poll()放入队列。在您的代码中,使用者都放置和拉出消息,而生产者根本不与队列进行交互。
答案 1 :(得分:0)
我意识到它就像
class Stater {
public static boolean STOP = false;
private Producer producer;
private Consumer consumer;
private ExecutorService producerService= Executors.newFixedThreadPool(PRODUCER_NUMBER, taxiFactory);
private ExecutorService consumerService= Executors.newFixedThreadPool(CONSUMER_NUMBER, clientFactory);
private void working() {
for (int i = 0; i < PRODUCER_NUMBER; i++) {
producerService.execute(() -> producer.get());
consumerService.execute(() -> consumer.run());
}
Starter.STOP = true;
producerService.shutdown();
consumerService.shutdown();
}
}
class Common {
private Queue<Message> emergencyQueue;
private BlockingQueue<Message> blockingQueue;
public void insertOrder(Message message) {
if (!blockingQueue.offer(message)) {
emergencyQueue.add(message);
}
}
public Message getOrder() {
if (emergencyQueue.isEmpty()) {
if (!blockingQueue.isEmpty()) {
return blockingQueue.poll();
} else {
return null;
}
} else {
return emergencyQueue.poll();
}
}
public boolean shouldStop() {
return blockingQueue.isEmpty() && emergencyQueue.isEmpty() && Starter.STOP;
}
}
class Consumer implements Runnable{
private Common common;
public void run(){
common.insertOrder(new Message());
}
}
class Producer implements Runnable{
private Common common;
public void run(){
while (!common.shouldStop()) {
Message message=common.getOrder();
if (message == null) {
Thread.sleep(new Random().nextInt(TIME_TO_WAIT));
}
}
}
}