User Tools

Site Tools


discussion

This is an old revision of the document!


Discussion

Comments, remarks, suggestions, corrections etcetera can be posted here.

Slawomir's Sleeping Barber

Please download the SleepingBarber.jar (the source code is in the jar), then run:

java -jar SleepingBarber.jar

The main logic is in the run() method of the Barber class:

public class Barber extends Thread
  {
  ...
  public void run( )
    {
    try
      {
      while ( true )
        {
        synchronized ( shop )
          {
          while ( !shop.isCustomerWaiting( ) )
            shop.wait( );
          if ( isAsleep )
            {
            isAsleep = false;
            setMessage( "awake ...", "wakes up" );
            shop.isCuttingChairBusy( false );
            setMessage( "ready ...", "frees his chair" );
            }
          shop.notifyAll( );
 
          setMessage( "working ...", "seats a customer" );
          while ( !shop.isCuttingChairBusy( ) )
            shop.wait( );
          }
 
        Customer customer = shop.getCurrentCustommer( );
        setMessage( "working ...", "starts " + customer );
        sleep( SleepingBarber.getRandomInt( SleepingBarber.MAX_TIME_HAIRCUT ) );
        setMessage( "working ...", "finishes " + customer );
        setMessage( "working ...", "--------------------" );
 
        synchronized ( shop )
          {
          shop.letCurrentCustomerOut( );
          shop.notifyAll( );
          while ( shop.isCuttingChairBusy( ) )
            shop.wait( );
          shop.currentCustomerDone( );
          if ( !shop.isCustomerWaiting( ) )
            {
            shop.isCuttingChairBusy( true );
            setMessage( "sleeping ...", "takes his chair" );
            isAsleep = true;
            setMessage( "sleeping ...", "--------------------" );
            setMessage( "sleeping ...", "goes to sleep" );
            setMessage( "sleeping ...", "--------------------" );
            }
          }
        }
      }
    catch ( InterruptedException e )
      {}
    }
  ...
  }

and the run() method of the Customer class:

public class Customer extends Thread
  {
  ...
  public void run( )
    {
    try
      {
      while ( true )
        {
        setMessage( "away ...", "--------------------" );
        setMessage( "away ...", "is away" );
        setMessage( "away ...", "--------------------" );
        sleep( SleepingBarber.getRandomInt( SleepingBarber.MAX_TIME_AWAY ) );
 
        synchronized ( shop )
          {
          setMessage( "entering ...", "enters the shop" );
          int number = shop.getNumber( );
          if ( number != Shop.NO_ROOM )
            {
            if ( shop.isBarberAsleep( ) )
              {
              setMessage( "waiting ...", "wakes the barber" );
              shop.notifyAll( );
              }
            if ( number != shop.nextServing( ) )
              setMessage( "waiting ...", "gets a chair" );
            else
              setMessage( "waiting ...", "stands by" );
            while ( shop.isBarberAsleep( ) || shop.isCuttingChairBusy( ) || !shop.isCurrentCustomerDone( )
                || number != shop.nextServing( ) )
              shop.wait( );
 
            setMessage( "serviced ...", "in cutting chair" );
            shop.letCurrentCustomerIn( this );
            shop.notifyAll( );
 
            setMessage( "serviced ...", "service started" );
            while ( !shop.isCuttingDone( ) )
              shop.wait( );
            setMessage( "serviced ...", "service done" );
            shop.isCuttingChairBusy( false );
            shop.notifyAll( );
            setMessage( "done ...", "out cutting chair" );
            }
          }
        }
 
      }
    catch ( InterruptedException e1 )
      {}
    }
  ...
  }

Sleeping Barber using Semaphore

Since we have just covered semaphore in the class, here is a solution to the Sleeping Barber problem using semaphores. Althought it may looks awkward using semaphores in this problem, I found it a good exerciese though. Also, I intentionally implemented the semaphors class, for practice and demonstration purpose.

/**************************************************************************
 classic sleeping barbar problem
 
 @version 1.0 
 @author	Hui Wang  
****************************************************************************/
public class  Main
{
  public static void main(String[] args)
  {
     final int numChairs = 5;
     final int numCustomers = 10;
 
     Shop shop = new Shop(numChairs);
 
     Barber bb = new Barber(shop);  // use constructor to pass info
     bb.start();
 
     for ( int i = 1; i <= numCustomers; i++ )
     {
       Customer ctr = new Customer(i,shop);
       ctr.start();
     }
 
 
  }
}
 
/*************************************************
/ semaphore class
**************************************************/
class MySemaphore 
{
   private int value;  // attribute
 
   public MySemaphore()  // constructor
   {
      this.value = 0;
   }
 
   public MySemaphore(int init) 
   {
      this.value = init;
   }
 
   public synchronized void signalMS()   // V
   {
      this.value++;
      if (this.value <= 1)  // oringinally 0
      {
         this.notify();
      }
   }
 
   public synchronized void waitMS()   // P
   {
      while (this.value == 0)
      {
        try{
           this.wait();
        }
        catch (InterruptedException ie) {}
      }
      this.value--;
   }
 
 } // end of MySemaphore
 
/*************************************************
/ Shop class
**************************************************/
class Shop
{
  // attributes
  private int numChairs ;
  private int waitingCount ;
 
  private MySemaphore customers;
  private MySemaphore barber;
  private MySemaphore mutex;
  private MySemaphore cutting;
 
  private int who;  // who is in service room
 
  // constructor
  public Shop(int nChairs) 
  {
     this.numChairs = nChairs;
     this.barber = new MySemaphore(0);
     this.customers = new MySemaphore(0);
 
     this.mutex = new MySemaphore(1);
     this.cutting = new MySemaphore(0);
 
     this.who = -1;
   }
 
   public void barberWorking() 
   {
      while (true)
      {
         System.out.println("**************\n--> # of waiting: " + waitingCount);
         if (waitingCount == 0)
            System.out.println("--> sleeping. ");
 
         this.customers.waitMS();  // wait for customers
         System.out.println("--> awken / coutinue work, # of waiting : "  
+ waitingCount);
 
         this.mutex.waitMS();
           this.waitingCount--;
           this.barber.signalMS();  // make self available
         this.mutex.signalMS();
 
         try
         {
             Thread.sleep((int)(Math.random() * 3000));  // wait for the thread to finish
         }
         catch (InterruptedException ie)
	 {
             System.out.println("Sleep failed");
         }
 
         System.out.println("--> working on " + who);
 
         cutting.waitMS();    // working
         System.out.println("--> finishing. ");
 
      }
 
  }
 
   public void customerWorking(int i)
   {
      System.out.print( i + " coming");
      this.mutex.waitMS();
      if ( waitingCount < numChairs )
      {  
         System.out.print(" --- already waitting # : " + waitingCount + " --- ");
         System.out.println( i + " entering");
         waitingCount++;
         customers.signalMS();   // increment customer, take seat
 
         mutex.signalMS();
 
         barber.waitMS();   // waiting / competing for barbar 
         this.who = i;   // I am the one getting the barber!
         System.out.println( i + " being served");
         try
         {
            Thread.sleep(2000));  // getting cut
         }
         catch (InterruptedException ie)
	 {
	    System.out.println("Sleep failed");
         }
 
         System.out.println( i + " being finished");
         cutting.signalMS();  // inform barber process 
 
      }
 
      else
      { 
         System.out.print(" --- alreay waitting # : " + waitingCount + " --- ");
         System.out.println( i + " leaving unhappily (full)");
         mutex.signalMS();  // leave the shop
      } 
   }
 
}  // end of Shop
 
 
/*************************************************
/ Barber class
**************************************************/
class Barber extends Thread
{
   private Shop shop;  // attribute
 
   public Barber(Shop s) // constructor
   {
     this.shop = s;
   }
 
   public void run() 
   {
      //while (true) 
      try
      {      	     
         Thread.sleep((int)(Math.random() * 3000));// wait for the thread to finish
      }
      catch (InterruptedException ie)
      {
	  System.out.println("Sleep failed");
      }
 
      shop.barberWorking();
   }
 }
 
 
/*************************************************
/ Customer class
**************************************************/
class Customer extends Thread 
{
   private int id;
   private Shop shop;
 
   public Customer(int cid, Shop s) 
   {
     this.id = cid;
     this.shop = s;
   }
 
   public void run() 
  {
      try
      {
         Thread.sleep((int)(Math.random() * 3000));  // wait for a while
      }
      catch (InterruptedException ie)
      {
	  System.out.println("Sleep failed");
      }
 
      shop.customerWorking(this.id);
  }
 
}
 
discussion.1193875866.txt.gz · Last modified: 2007/11/01 00:11 by huiwang

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki