具有多线程的Scala Singleton对象

时间:2013-11-12 16:10:44

标签: multithreading scala playframework singleton

使用play,我的控制器调用Foo服务,对象。此对象仅使用valimmutable data structures,将由多个客户端调用。

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

如果客户1拨打电话执行Foo.doQuery(),客户2对Foo.doQuery()的通话是否必须等待?

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

2 个答案:

答案 0 :(得分:10)

不,Scala对象并不意味着锁定(在java中同步),因此客户端2不必等待。如果您没有明确地向代码添加锁,客户端1,客户端2和客户端n都可以同时运行。

想想

object MyObject { ... }

作为

class MyClass(..) { ... }
lazy val MyObject = new MyClass(..)

可以通过“同步”来应用锁定。功能如下:

def doQuery = synchronized {
  ..
  ..
}

==编辑==

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

在您的情况下,我认为您可以将控制器实现为单例对象,因为不可变引用和数据结构很好..不可变。如果他们共享与否则无关紧要。

答案 1 :(得分:0)

为说明@harp seal pup的答案,这是带有输出的示例演示,
我们可以观察到可变变量myname受每个正在运行的线程的影响。
但是不可变的val thname不会影响或锁定每个线程。

object ObjectMultiThreadingTest {

  def main(args: Array[String]): Unit = {

    for (x <- 1 to 5) {
      var thread = new MyThread()
      thread.setName("Thread number :" + x.toString)
      thread.start()
    }
  }

  class MyThread extends Thread {
    override def run(): Unit = {
      Singleton.myname = this.getName
      Singleton.call(this.getName)
    }
  }

  object Singleton {
    var myname = "Singleton"
    def call(threadName: String): Unit = {
      val thName = threadName
      val random = new Random
      for (i <- 1 to 5) {
        println("My Name is set by " + myname)
        val sleeptime = random.nextInt(1000)
        println(
          "But, I am now running " + thName + ", sleeping for " + sleeptime
        )
        Thread.sleep(sleeptime)
      }
    }

  }
}

输出:

My Name is set by Thread number :5
My Name is set by Thread number :5
My Name is set by Thread number :5
But, I am now running Thread number :3, sleeping for 498
My Name is set by Thread number :5
My Name is set by Thread number :5
But, I am now running Thread number :5, sleeping for 968
But, I am now running Thread number :4, sleeping for 232
But, I am now running Thread number :2, sleeping for 562
But, I am now running Thread number :1, sleeping for 204
My Name is set by Thread number :5
But, I am now running Thread number :1, sleeping for 315
My Name is set by Thread number :5
But, I am now running Thread number :4, sleeping for 100
My Name is set by Thread number :5
But, I am now running Thread number :4, sleeping for 749
My Name is set by Thread number :5
But, I am now running Thread number :3, sleeping for 66
My Name is set by Thread number :5
But, I am now running Thread number :1, sleeping for 4
My Name is set by Thread number :5
But, I am now running Thread number :1, sleeping for 332
My Name is set by Thread number :5
But, I am now running Thread number :2, sleeping for 899
My Name is set by Thread number :5
But, I am now running Thread number :3, sleeping for 679
My Name is set by Thread number :5
But, I am now running Thread number :1, sleeping for 849
My Name is set by Thread number :5
But, I am now running Thread number :5, sleeping for 157
My Name is set by Thread number :5
But, I am now running Thread number :4, sleeping for 694
My Name is set by Thread number :5
But, I am now running Thread number :5, sleeping for 864
My Name is set by Thread number :5
But, I am now running Thread number :3, sleeping for 591
My Name is set by Thread number :5
But, I am now running Thread number :2, sleeping for 702
My Name is set by Thread number :5
But, I am now running Thread number :4, sleeping for 339
My Name is set by Thread number :5
But, I am now running Thread number :3, sleeping for 959
My Name is set by Thread number :5
But, I am now running Thread number :5, sleeping for 443
My Name is set by Thread number :5
But, I am now running Thread number :2, sleeping for 522
My Name is set by Thread number :5
But, I am now running Thread number :5, sleeping for 368
My Name is set by Thread number :5
But, I am now running Thread number :2, sleeping for 851
相关问题