gpt4 book ai didi

multithreading - 这段代码中是否存在潜在的饥饿问题,或者只是我?

转载 作者:行者123 更新时间:2023-12-02 00:44:24 25 4
gpt4 key购买 nike

我正在尝试学习 Scala,并发现它是一门很棒的语言。我学习"Beginning Scala"大卫波拉克。第三章中有一段代码,它说明了如何在没有同步块(synchronized block)的情况下编写多线程代码(这段代码是从书中复制的,可以从Apress site下载,我并没有在这里违反任何法律的意思):

import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}import java.util.Randomimport scala.collection.immutable.TreeHashMapobject 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)。我是对的吗?如果是这样,如何改进此代码以解决此问题?

最佳答案

首先,我认为您从书本示例中粘贴的代码中有很大一部分丢失了;这让你很难理解你的问题。

其次,确实可以递归调用 doSet() 多次,但在这种情况下不会发生 StackOverflowException,因为有一个优点:尾递归。 doSet() 在函数结束时被递归调用(在递归调用后不再进行处理)并且不能被覆盖(在对象内部定义),这使它有资格被优化为一个没有任何堆栈开销的循环。

在 2.8.0 中,有一个名为 @scala.annotation.tailrec 的注释,当用于 def 时,将确保 def 中的递归调用确实是尾递归的。

关于multithreading - 这段代码中是否存在潜在的饥饿问题,或者只是我?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1316080/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com