Skip to content

Instantly share code, notes, and snippets.

@mallman
Created February 3, 2013 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mallman/4703779 to your computer and use it in GitHub Desktop.
Save mallman/4703779 to your computer and use it in GitHub Desktop.
A ScalaSTM approach to the sleeping barber problem.
scalaVersion := "2.10.0"
libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.7"
/*
* A ScalaSTM approach to the sleeping barber problem. Build and run with sbt and a
* build.sbt file with these lines:
*
*
* scalaVersion := "2.10.0"
*
* libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.7"
*
*
* This is my first use of STM, so bugs and idiotic usage may abound.
*
* Links:
*
* http://www.bestinclass.dk/index.clj/2009/09/scala-vs-clojure-round-2-concurrency.html
* http://scala-stm.org/
* https://raw.github.com/paulp/sbt-extras/master/sbt
*
*/
object SleepingBarber extends App {
import annotation.tailrec
import util.Random._
import concurrent._
import ExecutionContext.Implicits._
import stm._
val queue = Ref(collection.immutable.Queue[Int]())
val tally = Ref(0).single
val SEATS = 3
def debug(msg: String, customer: Int) { println("%-35s %d" format (msg, customer)) }
def enterShop(customer: Int) {
debug("(c) entering shop", customer)
atomic { implicit t =>
if (queue().size < SEATS)
queue transform { _ :+ customer }
else
debug("(s) turning away customer", customer)
}
}
@tailrec def cutHair() {
atomic { implicit t =>
queue.single.await(!_.isEmpty)
debug("(b) cutting hair of customer", queue().head)
queue transform { _.tail }
tally += 1
}
Thread sleep (100 + nextInt(600))
cutHair
}
future { cutHair }
1 to 20 foreach { customer =>
enterShop(customer)
Thread sleep (100 + nextInt(200))
}
Thread sleep 2000
println(s"(!) ${tally()} customers got haircuts today")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment