Scala中的不变性和线程安全性 [英] Immutability and thread-safety in Scala

查看:192
本文介绍了Scala中的不变性和线程安全性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读实践中的Java并发这本书,当我读到有关 immutability 线程安全之间的关系我试图深入了解。所以,我发现至少有一个用例,在Java中构造一个不可变类会导致发布一个非正确构造的对象。

I'm reading the book Java concurrency in practice and when I read about the relation between immutability and thread-safety I tried to get deeper. So, I discovered that there is at least a use case in which the construction of an immutable class in Java can lead to the publishing of a non properly constructed object.

根据链接,如果该类的字段未解析 final ,编译器可以重新排序需要完成的语句以构造对象。事实上,根据这个链接,构建JVM需要执行这些非原子操作的对象:

According to this link, if the fields of the class are not declated final, the compiler could reorder the statements that needs to be done in order to construct the object. In fact, according to this link, to build an object the JVM needs to do these non-atomic operations:


  1. 分配一些内存

  2. 创建新对象

  3. 使用其默认值初始化其字段(布尔值为false,其他基元为0,对象为null)

  4. 运行构造函数,包括运行父构造函数

  5. 分配对新构造对象的引用

  1. allocate some memory
  2. create the new object
  3. initialise its fields with their default value (false for boolean, 0 for other primitives, null for objects)
  4. run the constructor, which includes running parent constructors too
  5. assign the reference to the newly constructed object

我的问题是:Scala怎么样?我知道Scala基于Java的并发模型,因此它基于相同的Java内存模型。例如,案例类 es线程安全是否存在上述构造问题?

My question is: what about Scala? I know that Scala is based on the concurrency model of Java, so it is based on the same Java Memory Model. For example, are case classes thread-safe wrt the above construction problem?

感谢所有人。

推荐答案

我在Stackoverflow和互联网上进行了一些深入的搜索。关于我所提出的问题,没有太多信息。我发现这个问题有一个有趣的答案: Scala final vs val for conurrency可见性

I've made some deep search on Stackoverflow and on the Internet. There is not so much information about the question I've made. I found this question on SO that has an interesting answer: Scala final vs val for concurrency visibility.

根据@retronym的建议,我使用了 javap -p A.class 来构造一个包含案例类 .class 文件,并由 scalac 。我发现班级

As proposed by @retronym I've used javap -p A.class to destructure a .class file containing a case class and compiled by scalac. I found that the class

case class A(val a: Any)

由scala编译器编译到相应的Java类中,该类声明其唯一属性 a final

is compiled by the scala compiler into a corresponding Java class that declares its unique attribute a as 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);
}

众所周知,案例类会自动为我们生成一堆实用程序。但也是这样一个简单的类

As we know, a case class in Scala generates automatically a bunch of utilities for us. But also a simple class like this

class A1(val a: Any)

被翻译成具有 final 属性的Java类。

is translated into a Java class that has a final attribute.

总结一下,我想我们可以说只有 val 属性的Scala类被翻译成一个<$ c $的相应Java类。 c> final 属性。由于JVM的JMM,在构建过程中,此Scala类应该是线程安全的

Summarizing, I think we can say that a Scala class that has only val attributes is translated into a corresponding Java class that has final attributes only. Due to the JMM of the JVM, this Scala class should be thread-safe during the construction process.

这篇关于Scala中的不变性和线程安全性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆