随机线程多线程

时间:2019-08-07 06:37:15

标签: java multithreading

我试图与几个生产者和消费者一起实现生产者-消费者模式。

我尝试做

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

2 个答案:

答案 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));
            }

          }
    }
}