我正在嘗試學習Scala,並發現它迄今爲止已經是一門很棒的語言。我從David Pollak學習"Beginning Scala"。在第3章中有一段代碼,它演示瞭如何編寫沒有同步塊的多線程代碼(該代碼是從本書複製的,可以從Apress site下載,我不打算在這裏打破任何規律):這段代碼中是否存在潛在的飢餓,還是僅僅是我?
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong} import java.util.Random import scala.collection.immutable.TreeHashMap object Multics { type MT = Map[String, Int] val info: AtomR[MT] = new AtomR(TreeHashMap.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 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) } } }
據我瞭解,有在功能doSet
潛在飢餓問題(不吉利的線程可能總是發生衝突,並導致StackOverflowException)。我是否對,如果是這樣,那麼如何改進這個代碼來解決這個問題呢?
你的代碼肯定是不完整的(一個無用的東西就是它不能編譯的事實;-)。請用http://uys.be/Multics.scala替換它(我沒有足夠的點來編輯問題)。 – opyate 2009-12-05 23:51:06