Multithreading Scala同步最佳实践

Multithreading Scala同步最佳实践,multithreading,scala,Multithreading,Scala,我已经开始学习Scala和Akka作为演员模型。例如,在命令式语言(如C)中,我可以使用几种不同的方法在二叉树上同步线程;简单的信号量或互斥、原子操作等 然而,Scala是一种功能性的面向对象语言,它可以利用Akka库实现参与者模型(例如)。在Scala中应该如何实现同步?假设我有一棵二叉树,我的程序要遍历它并对它执行不同的操作。例如,如何确保两个不同的参与者不会同时删除同一个节点 在较高的级别上,您可以使用Actor作为互斥对象:它逐个处理所有传入消息 在较低的级别(但不是在参与者级别),没有

我已经开始学习Scala和Akka作为演员模型。例如,在命令式语言(如C)中,我可以使用几种不同的方法在二叉树上同步线程;简单的信号量或互斥、原子操作等

然而,Scala是一种功能性的面向对象语言,它可以利用Akka库实现参与者模型(例如)。在Scala中应该如何实现同步?假设我有一棵二叉树,我的程序要遍历它并对它执行不同的操作。例如,如何确保两个不同的参与者不会同时删除同一个节点

  • 在较高的级别上,您可以使用Actor作为互斥对象:它逐个处理所有传入消息
  • 在较低的级别(但不是在参与者级别),没有什么可以阻止您使用普通的旧java并发原语
  • 如@Tanmay所建议的,使用不可变的数据结构,这样就不会有就地修改,也就不会有数据竞争
  • 有(尽管在最近的akka版本中已弃用)
  • 在较高的级别上,您可以使用Actor作为互斥对象:它逐个处理所有传入消息
  • 在较低的级别(但不是在参与者级别),没有什么可以阻止您使用普通的旧java并发原语
  • 如@Tanmay所建议的,使用不可变的数据结构,这样就不会有就地修改,也就不会有数据竞争
  • 有(尽管在最近的akka版本中已弃用)

  • 如果要对数据结构进行同步访问,只需使用
    AnyRef
    synchronized
    方法来同步块。例如:

    object Test {
      private val myMap = collection.mutable.Map.empty[Int, Int]
      def set(key: Int, value: Int): Unit = synchronized { myMap(key) = value }
      def get(key: Int): Option[Int] = synchronized { myMap.get(key) }
    }
    
    但是,使用actor的目的是避免线程之间相互阻塞,这会损害可伸缩性。Actor管理可变状态的方法是,状态对Actor实例是私有的,并且仅在响应消息时更新或访问。这是一个更复杂的设计,类似于:

    // define case classes Get, Set, Value here.
    class MapHolderActor extends Actor {
      private val myMap = collection.mutable.Map.empty[Int, Int] 
      def receive {
        case Get(key) => sender ! Value(myMap.get(key))
        case Set(key, value) => myMap(key) = value
      }
    }
    

    如果要对数据结构进行同步访问,只需使用
    AnyRef
    synchronized
    方法来同步块。例如:

    object Test {
      private val myMap = collection.mutable.Map.empty[Int, Int]
      def set(key: Int, value: Int): Unit = synchronized { myMap(key) = value }
      def get(key: Int): Option[Int] = synchronized { myMap.get(key) }
    }
    
    但是,使用actor的目的是避免线程之间相互阻塞,这会损害可伸缩性。Actor管理可变状态的方法是,状态对Actor实例是私有的,并且仅在响应消息时更新或访问。这是一个更复杂的设计,类似于:

    // define case classes Get, Set, Value here.
    class MapHolderActor extends Actor {
      private val myMap = collection.mutable.Map.empty[Int, Int] 
      def receive {
        case Get(key) => sender ! Value(myMap.get(key))
        case Set(key, value) => myMap(key) = value
      }
    }
    

    我打字时,om nom nom进来了!我的答案分别对应于om的第2点和第1点。om-nom-nom在我打字时进入!我的答案分别对应于om的第2点和第1点。正如所问的,答案是Scala与Java中的基本相同,您使用内置的
    synchronized
    HOF。但我怀疑你想问的问题是“为并发/并行程序实现线程安全的最佳实践是什么?”因此,故事就不那么简单了。演员和未来都有很长的路要走,每个人都有自己的长处和短处,在很大程度上是相辅相成的。谢谢你的回复@RandallSchulz。我是Scala新手,所以对特定语言的术语了解不多。然而,我知道并发编程,你是对的。我的问题更多的是关于如何实现线程安全。正如所问的,答案是Scala与Java中的基本相同,您使用内置的
    synchronized
    HOF。但我怀疑你想问的问题是“为并发/并行程序实现线程安全的最佳实践是什么?”因此,故事就不那么简单了。演员和未来都有很长的路要走,每个人都有自己的长处和短处,在很大程度上是相辅相成的。谢谢你的回复@RandallSchulz。我是Scala新手,所以对特定语言的术语了解不多。然而,我知道并发编程,你是对的。我的问题更多的是,如何实现线程安全。