加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala val必须同步进行并发访问?

发布时间:2020-12-16 09:02:08 所属栏目:安全 来源:网络整理
导读:在我读到的时候,Scala immutable val由于各种原因没有被转换为 Java final.这是否意味着必须保护从其他线程访问val以保证同步以保证可见性? 解决方法 作为对象成员,一旦初始化,val就不会在对象的生命周期中更改它们的值.因此,只要对象的引用没有在构造函数
在我读到的时候,Scala immutable val由于各种原因没有被转换为 Java final.这是否意味着必须保护从其他线程访问val以保证同步以保证可见性?

解决方法

作为对象成员,一旦初始化,val就不会在对象的生命周期中更改它们的值.因此,只要对象的引用没有在构造函数中转义,所以保证它们的值对所有线程都可见.事实上,他们获得了Java最终修饰符,如下所示:

object Obj {
  val r = 1

  def foo {
    val a = 1
    def bar = a
    bar
  }
}

使用javap:

...
private final int r;
...

public void foo();
...
   0:   iconst_1
   1:   istore_1
   2:   aload_0
   3:   iload_1
   4:   invokespecial   #31; //Method bar$1:(I)I
   7:   pop
...
private final int bar$1(int);
...
   0:   iload_1
   1:   ireturn
...

作为方法本地,它们仅在方法中使用,或者它们作为参数传递给嵌套方法或闭包(参见上面的提升条$1).闭包可能会传递给另一个线程,但它只有一个带有本地val值的final字段.因此,从创建它们到所有其他线程,它们是可见的,并且不需要同步.

请注意,这并未说明val指向的对象 – 它本身可能是可变的并且需要同步.

在大多数情况下,不能通过反射来违反上述内容 – Scala val成员声明实际上会生成一个具有相同名称的getter和一个getter访问的私有字段.尝试使用反射来修改字段将导致NoSuchFieldException.您可以修改它的唯一方法是在您的类中添加一个专门的注释,这将使专用字段受到保护,从而可以进行反射.我目前无法想到任何其他情况可能会改变声称为val的东西……

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读