我正在读这本书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 <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);
}
我们知道,Scala中的case类会自动为我们生成一堆实用程序.但也是这样一个简单的类
class A1(val a: Any)
被转换为具有final属性的Java类.
总而言之,我认为我们可以说只有val属性的Scala类被转换为只有最终属性的相应Java类.由于JVM的JMM,此Scala类在构建过程中应该是线程安全的.
原文地址:https://codeday.me/bug/20190706/1399174.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。