Scala中的不变性和线程安全性
我正在阅读实践中的Java并发书,当我读到不变性和线程安全之间的关系时,我试图深入了解。 所以,我发现至少有一个用例,在Java中构造一个不可变类可以导致发布一个非正确构造的对象。
根据此链接,如果类的字段未final
解析,则编译器可以重新排序需要完成的语句以构造对象。 实际上,根据此链接,要构建对象,JVM需要执行以下非primefaces操作:
- 分配一些内存
- 创建新对象
- 使用默认值初始化其字段(布尔值为false,其他基元为0,对象为null)
- 运行构造函数,其中包括运行父构造函数
- 为新构造的对象分配引用
我的问题是:Scala怎么样? 我知道Scala基于Java的并发模型,因此它基于相同的Java内存模型。 例如, case class
es线程安全是否与上述构造问题有关?
谢谢大家。
我在Stackoverflow和互联网上进行了一些深入的搜索。 关于我所提出的问题,没有太多信息。 我在SO上发现这个问题有一个有趣的答案: Scala final vs val用于并发可见性 。
正如@retronym所提出的,我使用了javap -p A.class
来javap -p A.class
一个包含case class
并由scalac
编译的.class
文件。 我找到了class级
case class A(val a: Any)
由scala编译器编译成相应的Java类,声明其唯一属性a
为final
。
Compiled from "A.scala" public class A implements scala.Product,scala.Serializable { // Final attribute private final java.lang.Object a; public static scala.Function1 andThen(scala.Function1); public static scala.Function1 compose(scala .Function1); 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 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); }
我们知道,Scala中的case class
自动为我们生成一堆实用程序。 但也是这样一个简单的类
class A1(val a: Any)
被转换为具有final
属性的Java类。
总而言之,我认为我们可以说只有val
属性的Scala类被转换为只有final
属性的相应Java类。 由于JVM的JMM,此Scala类在构建过程中应该是线程安全的。