Потоки Java не работают правильно со связанным списком - PullRequest
0 голосов
/ 04 апреля 2010

Привет, я работаю над проблемой спящего парикмахера. с добавлением приоритетного клиента, когда они прибывают, они идут впереди линии, и они являются следующими, чтобы подстричься.

Я использую linkedlist, и если я вижу приоритетного клиента, я помещаю его в начало списка, если клиент не является приоритетным, он переходит в конец списка. затем я вызываю метод wantHaircut, получая первый элемент списка.

Моя проблема в том, что клиент обрабатывается в том порядке, в котором он поступил, и приоритетный клиент должен ждать. Вот код, где все это происходит. есть идеи что я делаю не так? спасибо

 public void arrivedBarbershop(Customer c){

      if(waiting < numChairs && c.isPriority()){
          System.out.println("Customer " + c.getID() + ": is a priority customer - SITTING -");
          mutex.up();             
          customer_list.addFirst(c);
      }
      else if(waiting >= numChairs && c.isPriority()){
          System.out.println("Customer " + c.getID() + ": is a priority customer - STANDING -");
          mutex.up();
          customer_list.addFirst(c);
      } 
      else if(waiting < numChairs && !c.isPriority()){
           waiting++;
           System.out.println("Customer " + c.getID()  + ": arrived, sitting in the waiting room");
          customer_list.addLast(c);
           customers.up(); // increment waiting customers

       }
       else if(waiting >= numChairs && !c.isPriority()) {

         System.out.println("Customer " + c.getID() + ": went to another barber because waiting room was full - " + waiting + " waiting");
         mutex.up();
       }

      if(!customer_list.isEmpty()){
         this.wantHairCut(customer_list.removeFirst());
      }

   }

   public void wantHairCut(Customer c) {
          mutex.up();
          barber.down();  // waits for being allowed in barber chair
          System.out.println("Customer " + c.getID() + ": getting haircut");
          try {
             /** haircut takes between 1 and 2 seconds **/
              Thread.sleep(Barbershop.randomInt(1, 2) * 1000);
          } catch (InterruptedException e) { }
          System.out.println("Barber: finished cutting customer " + c.getID() + "'s hair");
          c.gotHaircut = true;          
          cutting.up();   // signals cutting has finished

          /** customer must pay now **/
          this.wantToCashout(c);          
   }

Ответы [ 4 ]

1 голос
/ 04 апреля 2010

вы должны использовать синхронизированные коллекции:

Collections.synchronizedList(List<Object> list)

этот метод возвращает синхронизированный экземпляр List на основе списка параметров

0 голосов
/ 05 апреля 2010

Ваш код добавляет клиента в список (начало или конец), а затем удаляет клиента из списка. Список содержит только одного клиента, поэтому клиенты обрабатываются в том порядке, в котором они были добавлены.

0 голосов
/ 04 апреля 2010

всякий раз, когда вы изменяете свой список, вы, вероятно, должны поместить этот код в синхронизированный блок.

Один способ сделать это:

synchronized(customer_list) {
 customer_list.addFirst(c);
}

Другой, чтобы у вас не былозакодировать это повсеместно:

public synchronized void addCustomerAtStart(Customer c) {
 customer_list.addFirst(c);
}

и затем заменить эту функцию.

То же самое, когда вы выполняете customer.up (), похоже, что его также нужно синхронизироватьв противном случае у вас может быть много противоречивого поведения.

Вам даже не нужно использовать этот "mutex.up ()". Совет: Если вам нужно синхронизировать потоки, вы, возможно, захотите взглянутьв CountDownLatch, очень прост в использовании, надежно работает для синхронизации потоков.

0 голосов
/ 04 апреля 2010

Я почти уверен, что логическая ошибка здесь:

  if(waiting < numChairs && c.isPriority()){
      System.out.println("Customer " + c.getID() + ": is a priority customer - SITTING -");
      mutex.up();             
      customer_list.addFirst(c);
  }
  else if(waiting >= numChairs && c.isPriority()){
      System.out.println("Customer " + c.getID() + ": is a priority customer - STANDING -");
      mutex.up();
      customer_list.addFirst(c);
  } 

И да, избегать копирования / вставки!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...