Created
February 3, 2013 21:39
-
-
Save mallman/4703779 to your computer and use it in GitHub Desktop.
A ScalaSTM approach to the sleeping barber problem.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
scalaVersion := "2.10.0" | |
libraryDependencies += "org.scala-stm" %% "scala-stm" % "0.7" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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