我正在读这本书Java concurrency in practice,当我读到不变性和线程安全之间的关系时,我试图深入了解.因此,我发现至少有一个用例,其中在Java中构造不可变类可以导致发布一个非正确构造的对象.
根据this链接,如果类的字段未最终解析,则编译器可以重新排序需要完成的语句以构造对象.实际上,根据this链接,要构建一个JVM需要执行这些非原子操作的对象:
>分配一些内存
>创建新对象
>使用其默认值初始化其字段(布尔值为false,其他基元为0,对象为null)
>运行构造函数,其中包括运行父构造函数
>为新构造的对象分配引用
我的问题是:Scala怎么样?我知道Scala基于Java的并发模型,因此它基于相同的Java内存模型.例如,案例类是否是线程安全的上述构造问题?
谢谢大家.
解决方法:
我在Stackoverflow和互联网上做了一些深入的搜索.关于我所提出的问题,没有太多的信息.我在SO上发现这个问题有一个有趣的答案:Scala final vs val for concurrency visibility.
正如@retronym所提出的,我使用javap -p A.class来构造一个包含case类并由scalac编译的.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
.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 A1(val a: Any)
被转换为具有final属性的Java类.
总而言之,我认为我们可以说只有val属性的Scala类被转换为只有最终属性的相应Java类.由于JVM的JMM,此Scala类在构建过程中应该是线程安全的.
标签:java,scala,thread-safety,immutability
来源: https://codeday.me/bug/20190706/1399174.html