Один производитель, несколько потребителей

1

Я работал над некоторым кодом, но мне нужна помощь. Я создал одного производителя и одного потребителя, однако мне нужно создать несколько потребителей, которые будут потреблять конкретную String от производителя, например, мне нужен потребитель, который будет потреблять именно "Move Left Hand".

Содержащийся в коде буфер, производитель, потребитель и основной. Я не уверен, как уведомить правильного потребителя и сравнить строку, которая должна быть потреблена. В его нынешнем виде у меня есть только один потребитель.

public class iRobotBuffer {
    private boolean empty = true;

    public synchronized String take() {
        // Wait until message is
        // available.
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
        // Toggle status.
        empty = true;
        // Notify producer that
        // status has changed.
        notifyAll();
        return message;
    }

    public synchronized void put(String message) {
        // Wait until message has
        // been retrieved.
        while (!empty) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
        // Toggle status.
        empty = false;
        // Store message.
        this.message = message;
        // Notify consumer that status
        // has changed.
        notifyAll();
    }
}

public class iRobotConsumer implements Runnable {
    private iRobotBuffer robotBuffer;

    public iRobotConsumer(iRobotBuffer robotBuffer){
        this.robotBuffer = robotBuffer;
    }

    public void run() {
        Random random = new Random();
        for (String message = robotBuffer.take();
                ! message.equals("DONE");
                message = robotBuffer.take()) {
            System.out.format("MESSAGE RECEIVED: %s%n", message);
            try {
                Thread.sleep(random.nextInt(5000));
            } catch (InterruptedException e) {}
        }
    }
}

public class iRobotProducer implements Runnable {
    private iRobotBuffer robotBuffer;
    private int number;

    public iRobotProducer(iRobotBuffer robotBuffer)
    {  
        this.robotBuffer = robotBuffer;
        //this.number = number;
    }

    public void run() {
        String commandInstructions[] = {
                "Move Left Hand",
                "Move Right Hand",
                "Move Both Hands",
        };
        int no = commandInstructions.length;
        int randomNo;
        Random random = new Random();


        for (int i = 0;
                i < commandInstructions.length;
                i++) {
            randomNo =(int)(Math.random()*no);
            System.out.println(commandInstructions[randomNo]);

            robotBuffer.put(commandInstructions[i]);
            try {
                Thread.sleep(random.nextInt(5000));
            } catch (InterruptedException e) {}
        }
        robotBuffer.put("DONE");
    }
}

public class iRobot
{
    public static void main(String[] args)
    {
        iRobotBuffer robotBuffer = new iRobotBuffer();
        (new Thread(new iRobotProducer(robotBuffer))).start();
        (new Thread(new iRobotConsumer(robotBuffer))).start();

    }//main
}//class
  • 0
    Спасибо за редактирование текста, есть ли шанс конструктивного ответа?
  • 0
    Что такое правильный потребитель ?
Показать ещё 6 комментариев
Теги:
multithreading
producer-consumer

2 ответа

4
Лучший ответ

Проблема заключается в вашем классе iRobotBuffer. Это должно быть очередь для поддержки нескольких производителей/потребителей. Я предоставил код для такой очереди, но java уже имеет реализацию (BlockingDeque<E>).

public class BlockingQueue<T> {

    private final LinkedList<T> innerList = new LinkedList<>();
    private boolean isEmpty = true;

    public synchronized T take() throws InterruptedException {
        while (isEmpty) {
            wait();
        }

        T element = innerList.removeFirst();
        isEmpty = innerList.size() == 0;
        return element;
    }

    public synchronized void put(T element) {
        isEmpty = false;
        innerList.addLast(element);
        notify();
    }
}
  • 1
    Большое спасибо! Как бы вы тогда убедились, что правильное сообщение отправляется соответствующему потребителю?
  • 0
    Тогда вам нужна маршрутизация. Вам нужен дополнительный класс, который принимает сообщение и помещает его в нужную очередь, в зависимости от критериев. В системах очередей сообщений они обычно маршрутизируются по темам. Это может помочь вам понять теорию, стоящую за этим: spring.io/blog/2010/06/14/…
Показать ещё 2 комментария
0

Насколько я понимаю, вы хотели бы 3 потребителя, по одному для каждой инструкции по перемещению. Вы можете использовать ArrayBlockingQueue из пакета java.util.concurrent iRobotBuffer класса iRobotBuffer. Кстати, вы можете взглянуть на другие параллельные коллекции - вам может понравиться.

Затем для потребителя вы можете peek() в то, что находится в очереди, и проверить, соответствует ли оно требованиям, а затем poll().

  • 0
    Большое спасибо, я раньше не работал с параллельными системами или несколькими потоками, так что это очень ново для меня. Не могли бы вы показать мне в коде, что вы имеете в виду? Я не знаком с этими пакетами вообще.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню