Reputation: 8353
I'm reading the book Java concurrency in practice and when I read about the relation between immutability and thread-safety I tried to get deeper. So, I discovered that there is at least a use case in which the construction of an immutable class in Java can lead to the publishing of a non properly constructed object.
According to this link, if the fields of the class are not declated final
, the compiler could reorder the statements that needs to be done in order to construct the object. In fact, according to this link, to build an object the JVM needs to do these non-atomic operations:
My question is: what about Scala? I know that Scala is based on the concurrency model of Java, so it is based on the same Java Memory Model. For example, are case class
es thread-safe wrt the above construction problem?
Thanks to all.
Upvotes: 4
Views: 825
Reputation: 8353
I've made some deep search on Stackoverflow and on the Internet. There is not so much information about the question I've made. I found this question on SO that has an interesting answer: Scala final vs val for concurrency visibility.
As proposed by @retronym I've used javap -p A.class
to destructure a .class
file containing a case class
and compiled by scalac
. I found that the class
case class A(val a: Any)
is compiled by the scala compiler into a corresponding Java class that declares its unique attribute a
as final
.
Compiled from "A.scala"
public class A implements scala.Product,scala.Serializable {
// Final attribute
private final java.lang.Object a;
public static <A extends java/lang/Object> scala.Function1<java.lang.Object, A
> andThen(scala.Function1<A, A>);
public static <A extends java/lang/Object> scala.Function1<A, A> compose(scala
.Function1<A, java.lang.Object>);
public java.lang.Object a();
public A copy(java.lang.Object);
public java.lang.Object copy$default$1();
public java.lang.String productPrefix();
public int productArity();
public java.lang.Object productElement(int);
public scala.collection.Iterator<java.lang.Object> productIterator();
public boolean canEqual(java.lang.Object);
public int hashCode();
public java.lang.String toString();
public boolean equals(java.lang.Object);
public A(java.lang.Object);
}
As we know, a case class
in Scala generates automatically a bunch of utilities for us. But also a simple class like this
class A1(val a: Any)
is translated into a Java class that has a final
attribute.
Summarizing, I think we can say that a Scala class that has only val
attributes is translated into a corresponding Java class that has final
attributes only. Due to the JMM of the JVM, this Scala class should be thread-safe during the construction process.
Upvotes: 1