jjzjj

java - 本地最终引用的安全发布

coder 2024-03-07 原文

我知道您可以通过写入对 finalvolatile 字段的引用来安全地发布一个非线程安全对象,该字段稍后将由另一个线程读取,前提是在发布时,创建对象的线程会丢弃对它的引用,这样它就不会再干扰或不安全地观察对象在其他线程中的使用。

但是在这个例子中,没有显式的 final 字段,只有 final 局部变量。 如果调用者放弃对 unsafe 的引用,这个发布是安全的吗?

void publish(final Unsafe unsafe) {
    mExecutor.execute(new Runnable() {
        public void run() {
            // do something with unsafe
        }
    }
}

我找到了一些问答,比如 this one ,这表明 final 局部变量被隐式“复制”到匿名类中。那是否意味着上面的例子等同于此?

void publish(final Unsafe unsafe) {
    mExecutor.execute(new Runnable() {
        final Unsafe mUnsafe = unsafe;
        public void run() {
            // do something with mUnsafe
        }
    }
}

编辑澄清:

Unsafe 可以是任何东西,但可以这样说:

public class Unsafe {
    public int x;
}

mExecutor是满足Executor契约的任何东西。

最佳答案

虽然,诚然,我并不完全确定我是否理解了您问题的真正要点,并且(正如评论中指出的那样)这个问题在您的特定情况下可能并不是真正的问题,也许可以从测试/示例中获得相关见解

考虑以下类(class):

import java.util.concurrent.ExecutorService;

class Unsafe
{

}

class SafePublication
{
    private final ExecutorService mExecutor = null;

    public void publish(final Unsafe unsafe)
    {
        mExecutor.execute(new Runnable()
        {
            @Override
            public void run()
            {
                // do something with unsafe
                System.out.println(unsafe);
            }
        });
    }
}

编译得到两个.class文件:

  • SafePublication.class
  • 内部类的SafePublication$1.class

反编译内部类的类文件会产生以下内容:

class SafePublication$1 implements java.lang.Runnable {
  final Unsafe val$unsafe;

  final SafePublication this$0;

  SafePublication$1(SafePublication, Unsafe);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1                  // Field this$0:LSafePublication;
       5: aload_0
       6: aload_2
       7: putfield      #2                  // Field val$unsafe:LUnsafe;
      10: aload_0
      11: invokespecial #3                  // Method java/lang/Object."<init>":()V
      14: return

  public void run();
    Code:
       0: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: aload_0
       4: getfield      #2                  // Field val$unsafe:LUnsafe;
       7: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      10: return
}

可以看到对于final参数,确实在这个类中引入了一个字段。这个字段是 val$unsafe,它是一个 final field in the class file sense , 并在构造函数中初始化。

(这并不完全等同于您发布的第二个代码片段,因为第二个代码片段包含两个 final 字段,并且它们都使用相同的值初始化。但是关于安全问题发布,效果应该是一样的)。

关于java - 本地最终引用的安全发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38251982/

有关java - 本地最终引用的安全发布的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  5. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  6. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  7. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  9. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  10. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

随机推荐