views:

146

answers:

4

Hi I am working on the sleeping barber problem. with the addition of having priority customer when they arrive they go in the front of the line and they are the next ones to get a haircut.

I'm using a linkedlist and if I see a priority customer I put him in the beginning of the list, if the customer is not priority he goes to the end of the list. then I call the wantHaircut method getting the first element of the list.

my problem is that the customer are being processed in the order they arrive, and the priority customer have to wait. here is the code where it all happens. any ideas what I am doing wrong? thanks

 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);          
   }
+1  A: 

you must use synchronized collections:

Collections.synchronizedList(List<Object> list)

this method returns synchronized List instanse based on parameter list

Frostman
I don't know if I am doing it wrong, but this is not working either...list = Collections.synchronizedList(customer_list);
it's only means that error contains in logic
Frostman
do you what the logic error is ? I can't seem to figure it out.
unfortunately, i don't see mistakes
Frostman
A: 

I'm pretty sure the logical mistake is here:

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

And yes, avoid copy/paste programming!

Roman
I don't seem to find anything wrong with the code above....
@user69514: absolutely same blocks of code in both parts of if/else construction.
Roman
they're supposed to do the same thing. one will print STANDING and the other one SITTING. one is if there are more customers than chair, and the other one if there are less customers than chair. I don't see how that is causing the program not to work correctly...
A: 

whenever you modify your list, you should probably put that code on a synchronized block.

One way to do it:

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

Another, so that you don't have to code that all over the place:

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

and then substitute that function.

Same thing when you do customer.up(), that looks like it needs to be synchronized as well, otherwise you might be getting a lot of inconsistent behavior.

You shouldn't even need to use that "mutex.up()" Tip: If you have to synchronize threads, you might want to take a look at CountDownLatch, very easy to use, works solidly for thread synchronization.

Gubatron
this solution didn't work either... I don't know where my mistake is...
A: 

Your code adds a customer to the the list (begin or end) then removes a customer from the list. The list only ever contains one customer at most, so customers are processed in the order they are added.

Skip Head