Как использовать синхронизированный в 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
}
}
Я не нашел хорошего руководства для использования synchronized
метода в Scala. Может ли кто-нибудь сообщить мне, если вышеуказанный код исправит мою проблему.
EDIT: Основываясь на комментариях ниже, я думаю, что AtomicLong
- лучшее решение для меня:
import java.util.concurrent.atomic.AtomicLong
private val ctr = new AtomicLong
def getCtr = ctr.incrementAndGet
Ответы
Ответ 1
Если вы не хотите 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
так что вы вызываете метод вашего объекта, как вы это делаете toString
и this.toString
.