我可以将Scala中的局部变量设置为Volatile,因为在Java中它是不可能的吗?

据我所知,Java和Scala中的字段标记为Volatile,提供了在关系之前发生的事情.

在Java中,不可能在方法中将局部变量设置为volatile.然而,Scala编译器似乎允许这样的事情,如下面的代码所示:

def test: Unit = {
  @volatile var doNotStop = true 
}

它的实际工作方式与Java相同吗?这些代码的语义是什么?它在运行时如何看待字节代码和JVM?

在Java中,如果赋予闭包这样的变量可以被另一个线程修改,因此,它必须是最终的,对吧?

解决方法:

TL; DR:@volatile注释在应用于局部变量时看起来被忽略,除非变量可以从闭包内的本地范围转义.

为了确保这一点,我们可以检查对应于以下代码段的字节码

class Foo {
    def test: Unit = {
      @volatile var doNotStop: Boolean = true 
    }
}

使用scalac获得的类文件可以使用javap -c -v -p进行反编译.这是测试方法的相关部分:

public void test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_1
         1: istore_1
         2: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            1       1     1 doNotStop   Z
      ...

请注意,没有与任何易失性访问相关的信息.

如果我们选择将doNotStop声明为实例变量,那么javap会显示以下带有清除volatile标志的字段声明:

private volatile boolean doNotStop;
  descriptor: Z
  flags: ACC_PRIVATE, ACC_VOLATILE

但是,您对局部变量逃避其范围的关注是完全有效的!我们试试这个:

class Foo {
    def test = {
        var doNotStop: Boolean = true
        () => doNotStop = false
    }
}

使用javap -p(这次不需要查看字节码或标志)给出了以下定义:

public class Foo {
  public scala.Function0<scala.runtime.BoxedUnit> test();
  public static final void $anonfun$test$1(scala.runtime.BooleanRef);
  public Foo();
  private static java.lang.Object $deserializeLambda$(java.lang.invoke.SerializedLambda);
}

你可以看到闭包已被编译成自己的方法,名为$anonfun $test $1,它接受一个BooleanRef.此BooleanRef是doNotStop的运行时表示形式并包装了一个布尔值.有关上一个声明的更多信息,您可以查看related Java documentation.

现在为揭示:如果我们再次使doNotStop变得不稳定怎么办?

public class Foo {
  public scala.Function0<scala.runtime.BoxedUnit> test();
  public static final void $anonfun$test$1(scala.runtime.VolatileBooleanRef);
  public Foo();
  private static java.lang.Object $deserializeLambda$(java.lang.invoke.SerializedLambda);
}

这个类大致保持不变,但$anonfun $test $1现在需要一个VolatileBooleanRef.猜猜它的内部布尔值是如何实现的:

volatile public boolean elem;

这里的语义非常清楚:您的非局部布尔变量在运行时表示为BooleanRef实例的字段.正是这个字段可能被注释标记为易失性.你去吧,@ volatile在那里很有用!

回答你的第二个问题:Java的闭包仅接近“有效最终”的值,这将禁止这种模式,其中doNotStop的值在闭包内发生变化.您当然可以使用与此处所做的相同的方式实现它,使用对(易失性)BooleanRef的“有效最终”引用,其elem可以由闭包自由修改.

原文地址:https://codeday.me/bug/20190527/1162232.html

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

相关推荐


共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 TwemojiTwemoji是Twitter开源的其完整的Emoji表情图片。开发者可以去GitHub下载完整的表情库,并把这些表情加入到自己的应用或网页中。使用示例:var i = 0;twemoji.parse(  ’emoji, m\u276
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即两个对象在内存中的首地址;equals比较字符串中所包含的内容是否相同。publicstaticvoidmain(String[]args){​ Strings1="abc"; Strings2=newString("abc");​ System.out.println(s1==s2)
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala怎么使用”吧!语法scala...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相信很多人在Scala是一种什么语言问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相信很多人在Scala Trait怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日常操作中,相信很多人在Scala类型检查与模式匹配怎么使用问题上存在疑惑,小编查阅了各式资料,整理...
这篇文章主要介绍“scala中常用但不常见的符号有哪些”,在日常操作中,相信很多人在scala中常用但不常见的符号有哪些问题上存在疑惑,小编查阅了各式资料,整理...
本篇内容主要讲解“Scala基础知识有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala基础知识有哪些”...
本篇内容介绍了“scala基础知识点有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本篇内容介绍了“Scala下划线怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...
本篇内容主要讲解“Scala提取器怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala提取器怎么使用”...
这篇文章主要讲解了“Scala基础语法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala基础语法有...
本篇内容主要讲解“Scala方法与函数怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala方法与函数怎...
这篇文章主要讲解了“scala条件控制与循环怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“scala条...
这篇文章主要介绍“scala函数怎么定义和调用”,在日常操作中,相信很多人在scala函数怎么定义和调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操
这篇文章主要介绍“scala如何声明变量”,在日常操作中,相信很多人在scala如何声明变量问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对...
这篇文章主要讲解了“scala的Map和Tuple怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“scala的Ma...
这篇文章主要介绍“scala的隐式参数有什么作用”,在日常操作中,相信很多人在scala的隐式参数有什么作用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
本篇内容主要讲解“Scala怎么进行文件写操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala怎么进行文件...
这篇文章主要讲解了“Scala怎么声明数组”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala怎么声明数组...