如何在Scala中使用synchronized?

时间:2016-01-19 12:59:46

标签: scala

我有以下代码:

object Foo {
 private var ctr = 0L

 def bar = {
   ctr = ctr + 1
   // do something with ctr
 }
}

要求是ctr值只能使用一次。在我的情况下,ctr的相同值被重用。我的理论是,这是因为Foo.bar在不同的线程中同时被调用(这是我可以得出的唯一结论)。我有以下修改过的代码作为修复。

object Foo {
 private var ctr = 0L
 def getCtr = synchronized{
   ctr = ctr + 1
   ctr
 }
 def bar = {
   val currCtr = getCtr
   // do something with currCtr
 }
}

我找不到在Scala中使用synchronized方法的好指南。如果上述代码能解决我的问题,任何人都可以告诉我。

编辑:根据以下评论,我认为AtomicLong对我来说是最好的解决方案:

import java.util.concurrent.atomic.AtomicLong
private val ctr = new AtomicLong
def getCtr = ctr.incrementAndGet

1 个答案:

答案 0 :(得分:29)

如果您不想要AtomicInteger,请按以下步骤使用synchronized

object Foo {
 private var ctr = 0L
 def getCtr = this.synchronized {
   ctr = ctr + 1
   ctr
 }
 def bar = {
    val currCtr = getCtr
    // do something with currCtr
  }
}

您需要在某个对象上进行同步。在这种情况下,您的当前对象是this

它相当于java的

synchronized(this) {
   return ctr++;   
}

Scala没有synchronized方法作为java,只是块。

修改

要回答以下评论中的问题:synchronized可用作课程AnyRef中的方法:

https://www.scala-lang.org/api/current/scala/AnyRef.html

final def synchronized[T0](arg0: ⇒ T0): T0

所以你要调用对象的方法,就像你toStringthis.toString一样。