discussion
This is an old revision of the document!
Table of Contents
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