Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use synchronized in Scala?

Tags:

scala

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 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  } } 

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.

EDIT: 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 
like image 332
Jus12 Avatar asked Jan 19 '16 12:01

Jus12


People also ask

What is the use of synchronized method?

Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods.

How does synchronized keyword work?

When we use a synchronized block, Java internally uses a monitor, also known as monitor lock or intrinsic lock, to provide synchronization. These monitors are bound to an object; therefore, all synchronized blocks of the same object can have only one thread executing them at the same time.

Can we use synchronized in static method?

static methods can be synchronized. But you have one lock per class. when the java class is loaded coresponding java.

Is synchronized method more efficient?

If you synchronize a code block within that method then more than one thread can execute the method simultaneously, but only one thread can enter the synchronized block at a time. From this we can conclude that synchronizing on the smallest possible code block required is the most efficient way to do it.


1 Answers

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   } } 

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

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

this.synchronized {    ctr = ctr + 1    ctr } 

It is equivalent of java's

synchronized(this) {    return ++ctr;    } 

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

Edit

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 

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

like image 125
Łukasz Avatar answered Sep 29 '22 07:09

Łukasz