微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java – Scala中的不变性和线程安全性

我正在读这本书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类在构建过程中应该是线程安全的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐