Skip to content

Instantly share code, notes, and snippets.

@lazyval
Created May 2, 2012 05:10
Show Gist options
  • Save lazyval/2573954 to your computer and use it in GitHub Desktop.
Save lazyval/2573954 to your computer and use it in GitHub Desktop.
package com.github.omnomnom
import java.util.concurrent.Semaphore
import concurrent.Lock
object SleepingBarber extends App {
val NCustomers = 12
val NChairs = 5
val CutTime = 10
val VisitInterval = 5
val customers = new Semaphore(1, true);
val barbers = new Semaphore(1, true);
val mutex = new Lock();
var freeChairs = NChairs
object Barber extends Thread {
override def run() {
while (true) {
println("Barber: I'm waiting for a customer.");
customers.acquire(); // Wait if # of customers is zero
// We have at least one customer at this point.
mutex.acquire(); // protect "freeChairs"
freeChairs += 1; // a customer moves to the barber chair
barbers.release(); // the barber is ready to cut hair
mutex.release();
// Cut Hair
println("Barber: I'm ready to cut.");
Thread.sleep(CutTime);
}
}
}
class Customer(customerId: Int) extends Thread("Customer " + customerId) {
override def run() {
println(getName + ": I need to have my hair cut.");
mutex.acquire();
if (freeChairs > 0) {
println(getName + ": I sit down and wait.");
freeChairs; // a chair is occupied
customers.release(); // wake up the barber (if necessary)
mutex.release(); // "freeChairs" is no longer accessed
println(getName + ": I'm waiting for my turn...");
barbers.acquire(); // wait for my turn
// Hair Cut
println(getName + ": It's my turn. \\(^o^)/");
Thread.sleep(CutTime);
println(getName + ": Thanks! Bye. (^o^)/~");
} else {
// There is no chairs. Customer must give up.
println(getName + ": the barber shop is full. (;_;)");
mutex.release(); // "freeChairs" is no longer accessed
}
}
}
Barber.start();
(1 to NCustomers).foreach(i => {
Thread.sleep(VisitInterval)
new Customer(i).start()
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment