私はScalaを学び、今のところ素晴らしい言語を見つけようとしています。私は"Beginning Scala"からDavid Pollakによって学びます。第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