具有多线程的Scala Singleton对象

Kev*_*ith 6 singleton multithreading scala playframework

使用play,我的控制器调用Foo服务,一个对象.此对象仅使用val's' immutable data structures,将由多个客户端调用.

当我的Controller调用Foo.doQuery()多个线程时,会发生什么?

如果客户端1拨打电话,Foo.doQuery()客户2的呼叫是否Foo.doQuery()必须等待?

我很好奇我是否应该简单地为每个实例创建一个新类Foo,但是我想知道val在多线程环境中使用Scala单例时会发生什么.

har*_*pup 10

不,Scala对象并不意味着锁定(java中的"synchronized"),因此客户端2不必等待.如果您没有向代码显式添加锁,则客户端1,客户端2和客户端n都可以并发运行.

考虑到

object MyObject { ... }
Run Code Online (Sandbox Code Playgroud)

class MyClass(..) { ... }
lazy val MyObject = new MyClass(..)
Run Code Online (Sandbox Code Playgroud)

可以使用'synchronized'函数应用锁定,如下所示:

def doQuery = synchronized {
  ..
  ..
}
Run Code Online (Sandbox Code Playgroud)

==编辑==

至于您在注释中的问题,线程(或调用)堆栈和变量共享与您的控制器使用不可变引用和/或不可变数据结构无关.重要的是定义变量的位置.如果在方法(方法变量)中定义变量(无论是val还是var),那么每次调用该方法时,该变量都是为调用线程创建的.另一方面,如果在类或对象级别(实例变量)定义变量,则对实例方法的所有调用始终共享相同的实例变量.

在你的情况下,我认为你可以将你的控制器实现为一个单例对象,因为不可变的引用和数据结构很好..不可变.它们是否共享并不重要.