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

Java Scala中的不变性和线程安全性,java,scala,thread-safety,immutability,Java,Scala,Thread Safety,Immutability,我正在读这本书,当我读到不变性和线程安全性之间的关系时,我试图深入了解。因此,我发现至少有一个用例,在Java中构造一个不可变的类可以导致发布一个未正确构造的对象 根据link,如果类的字段没有被分离final,编译器可以重新排序需要执行的语句,以便构造对象。事实上,根据link,要构建对象,JVM需要执行以下非原子操作: 分配一些内存 创建新对象 使用其默认值初始化其字段(布尔值为false,其他原语为0,对象为null) 运行构造函数,其中也包括运行父构造函数 将引用指定给新构造的对象 我的

我正在读这本书,当我读到不变性和线程安全性之间的关系时,我试图深入了解。因此,我发现至少有一个用例,在Java中构造一个不可变的类可以导致发布一个未正确构造的对象

根据link,如果类的字段没有被分离
final
,编译器可以重新排序需要执行的语句,以便构造对象。事实上,根据link,要构建对象,JVM需要执行以下非原子操作:

  • 分配一些内存
  • 创建新对象
  • 使用其默认值初始化其字段(布尔值为false,其他原语为0,对象为null)
  • 运行构造函数,其中也包括运行父构造函数
  • 将引用指定给新构造的对象
  • 我的问题是:Scala呢?我知道Scala基于Java的并发模型,所以它基于相同的Java内存模型。例如,
    case class
    es线程安全wrt是否就是上述构造问题


    感谢大家。

    我在Stackoverflow和互联网上进行了深入搜索。关于我提出的问题,没有太多的信息。我发现这个问题,所以有一个有趣的答案:

    正如@retronym所建议的,我使用了
    javap-pa.class
    来解构一个
    .class
    文件,该文件包含一个
    案例类
    ,并由
    scalac
    编译。我发现这个班

    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);
    }
    
    转换为具有
    final
    属性的Java类


    总之,我认为我们可以说,一个只有
    val
    属性的Scala类被转换成一个只有
    final
    属性的对应Java类。由于JVM的JMM,这个Scala类在构建过程中应该是线程安全的。

    也可以将其作为一个答案发布?@SteveWaldman,你能总结一下你给出的问题的答案吗?我试着读了一遍,但是信息太多了,而且重点与我的问题不完全相同。非常感谢。没有人接受答案。一张海报为Scala的核心不可变表是线程安全的这一说法进行了长时间的论证,只要您从
    Scala.\u
    包之外访问它们,但我认为这个答案最终没有说服力。我认为线程安全问题在实践中不太可能,例如列表和向量,但我认为Java内存模型足够灵活,如果不同步访问,就无法保证安全性。我觉得这非常令人失望,但到目前为止,还没有人向我提出有说服力的理由来保证安全。请看@axel22的评论。对不起@DanielL.,你是什么意思?
    class A1(val a: Any)