如何在 Scala 中使用同步?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34877487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 07:57:12  来源:igfitidea点击:

How to use synchronized in Scala?

scala

提问by Jus12

I have the following code:

我有以下代码:

object Foo {
 private var ctr = 0L

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

The requirement is that a ctrvalue should be used only once. In my case the same value of ctris getting reused. My theory is that this happens because Foo.baris called concurrently in different threads (this is the only conclusion I could draw). I have the following modified code as a fix.

要求是一个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
 }
}

I could not find a good guide for using the synchronizedmethod in Scala. Can anyone let me know if the above code will fix my problem.

我找不到synchronized在 Scala 中使用该方法的好指南。任何人都可以让我知道上面的代码是否可以解决我的问题。

EDIT: Based on the comments below, I think AtomicLongis the best solution for me:

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

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

回答by ?ukasz

If you don't want an AtomicInteger, here is how to use synchronized

如果你不想要一个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
  }
}

You need to synchronize on some object. In this case on your current object which is this.

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

In short: Scala's format is (and the block can return a value)

简而言之:Scala 的格式是(并且块可以返回一个值)

this.synchronized {
   ctr = ctr + 1
   ctr
}

It is equivalent of java's

它相当于java的

synchronized(this) {
   return ++ctr;   
}

Scala does not have synchronizedmethods as java, just blocks.

Scala 没有synchronizedjava那样的方法,只有块。

Edit

编辑

To answer the question from comment below: synchronizedcan be used as a method from class AnyRef:

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

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

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

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

so you are calling a method of your object, just like you would do toStringand this.toString.

所以你在呼唤你的对象的方法,就像你会做toStringthis.toString