Skip to content

Commit

Permalink
Added the lock-free concurrent code from listing 3-8
Browse files Browse the repository at this point in the history
  • Loading branch information
derekwyatt committed Oct 24, 2010
1 parent b7a7723 commit bd525d6
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions beginning-scala/Multics.scala
@@ -0,0 +1,55 @@
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}
import java.util.Random
import scala.collection.immutable.Map

object Multics {
type MT = Map[String, Int]
val info: AtomR[MT] = new AtomR(Map.empty)
val clashCnt = new AtomicLong

def main(argv: Array[String]) {
runThread {
repeatEvery(1000) {
println("Clash Count: "+clashCnt+" Total: "+ info.get.foldLeft(0)(_ + _._2))
}
}
for (i <- 1 to 2000) runThread {
var cnt = 0
val ran = new Random
val name = "K"+i
doSet(info){old => old + (name -> 0)}
repeatEvery(ran.nextInt(100)) {
doSet(info){old => old + (name -> (old(name) + 1))}
cnt = cnt + 1
if (cnt != info.get()(name))
throw new Exception("Thread: "+name+" failed")
}
}
}

def runThread(f: => Unit) = {
(new Thread(new Runnable {
def run(): Unit = f
})).start
}

def doSet[T](atom: AtomR[T])(update: T => T) {
val old = atom.get
if (atom.compareAndSet(old, update(old))) ()
else {
clashCnt.incrementAndGet
doSet(atom)(update)
}
}

def repeatEvery(len: => Int)(body: => Unit): Unit = {
try {
while(true) {
Thread.sleep(len)
body
}
} catch {
case e => e.printStackTrace; System.exit(1)
}
}
}

0 comments on commit bd525d6

Please sign in to comment.