Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala val has to be guarded with synchronized for concurrent access?

As I read, Scala immutable val doesn't get translated to Java final for various reasons. Does this mean that accessing a val from an other Thread must be guarded with synchronization in order to guarantee visibility?

like image 316
ron Avatar asked Mar 16 '11 14:03

ron


1 Answers

the assignment to val itself is fine from a multi-threading point of view, because you have to assign val a value when you declare it and that value can't be changed in the future (so if you do a val s="hello", s is "hello" from its birth on: no thread will ever read another value). There are a couple of caveats, however:

1 - if you assign an instance of a mutable class to val, val by itself will not "protect" the internal state of the class from changing.

class Foo(s:String) { var thisIsMutable=s }
// you can then do this
val x = new Foo("hello")
x.thisIsMutable="goodbye"
// note that val guarantees that x is still the same instance of Foo
// reassigning x = new Foo("goodbye") would be illegal

2 - you (or one of your libraries...) can change a val via reflection. If this happens two threads could indeed read a different value for your val

import java.lang.reflect.Field
class Foo { val foo=true } // foo is immutable

object test {
  def main(args: Array[String]) {  
        val f = new Foo
        println("foo is " + f.foo) // "foo is true"

        val fld = f.getClass.getDeclaredField("foo")
        fld.setAccessible(true) 
        fld.setBoolean(f, false) 
        println("foo is " + f.foo) // "foo is false"
  }
}
like image 193
Paolo Falabella Avatar answered Oct 14 '22 09:10

Paolo Falabella