如何在 Scala 中使用同步? [英] How to use synchronized in Scala?

查看:45
本文介绍了如何在 Scala 中使用同步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

object Foo {
 private var ctr = 0L

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

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

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

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

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

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

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

Based on the comments below, I think AtomicLong is the best solution for me:

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

推荐答案

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

If you don't want an AtomicInteger, here is how to use 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.

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

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

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

this.synchronized {
   ctr = ctr + 1
   ctr
}

相当于java的

synchronized(this) {
   return ++ctr;   
}

Scala 没有像 java 那样的 synchronized 方法,只有块.

Scala does not have synchronized methods as java, just blocks.

编辑

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

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

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

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

因此您正在调用对象的方法,就像您执行 toStringthis.toString 一样.

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

这篇关于如何在 Scala 中使用同步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆