2015-03-29 2 views
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

Что такое * правильный потребитель *? – m0skit0

+1

Редактирование - это всего лишь вопрос помощи людям в чтении кода. Это неконструктивно. –

ответ

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

Тогда вам нужна маршрутизация. Вам нужен дополнительный класс, который принимает сообщение и помещает его в нужную очередь, в зависимости от критериев. В системах очереди сообщений они обычно маршрутизируются по темам. Это может помочь вам понять теорию, стоящую за ней: http://spring.io/blog/2010/06/14/understanding-amqp-the-protocol-used-by-rabbitmq/ – sturcotte06

+0

Спасибо! У вас есть идеи по настройке маршрутизации по темам? Ссылка отсутствует. –

0

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

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

+0

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

Смежные вопросы