如何在Scala中使用synchronized?

How to use synchronized in Scala?

我有以下代码:

1
2
3
4
5
6
7
8
object Foo {
 private var ctr = 0L

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

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

1
2
3
4
5
6
7
8
9
10
11
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是我的最佳解决方案:

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


如果你不想要一个AtomicInteger,这里是如何使用synchronized

1
2
3
4
5
6
7
8
9
10
11
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的

1
2
3
synchronized(this) {
   return ctr++;  
}

Scala没有EDCOX1和1种方法作为Java,只是块。

编辑

回答下面评论中的问题:synchronized可用作AnyRef类的一种方法:

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

1
final def synchronized[T0](arg0: ? T0): T0

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