测试最终字段的初始化安全性

2024-07-04

我试图简单地测试 JLS 保证的最终字段的初始化安全性。这是为了我正在写的一篇论文。但是,根据我当前的代码,我无法让它“失败”。有人可以告诉我我做错了什么,或者这只是我必须一遍又一遍地运行然后在一些不幸的时机看到失败的事情吗?

这是我的代码:

public class TestClass {

    final int x;
    int y;
    static TestClass f;

    public TestClass() {
        x = 3;
        y = 4;
    }

    static void writer() {
        TestClass.f = new TestClass();
    }

    static void reader() {
        if (TestClass.f != null) {
            int i = TestClass.f.x; // guaranteed to see 3
            int j = TestClass.f.y; // could see 0

            System.out.println("i = " + i);
            System.out.println("j = " + j);
        }
    }
}

我的线程这样称呼它:

public class TestClient {

    public static void main(String[] args) {

        for (int i = 0; i < 10000; i++) {
            Thread writer = new Thread(new Runnable() {
                @Override
                public void run() {
                    TestClass.writer();
                }
            });

            writer.start();
        }

        for (int i = 0; i < 10000; i++) {
            Thread reader = new Thread(new Runnable() {
                @Override
                public void run() {
                    TestClass.reader();
                }
            });

            reader.start();
        }
    }
}

我已经运行过这个场景很多很多次了。我当前的循环生成了 10,000 个线程,但我已经完成了 1000 个、100000 个甚至 100 万个线程。还是没有失败。我总是看到 3 和 4 这两个值。我怎样才能让这个失败?


我写了规范。 TL;这个答案的 DR 版本只是因为它may看到 y 为 0,这并不意味着它是保证y 见 0。

在这种情况下,最终的字段规范保证您将看到 x 为 3,正如您所指出的。将编写器线程视为有 4 条指令:

r1 = <create a new TestClass instance>
r1.x = 3;
r1.y = 4;
f = r1;

您可能看不到 x 的 3 的原因是编译器重新排序了此代码:

r1 = <create a new TestClass instance>
f = r1;
r1.x = 3;
r1.y = 4;

在实践中通常实现最终字段的保证的方式是确保构造函数在任何后续程序操作发生之前完成。想象一下有人在 r1.y = 4 和 f = r1 之间竖起了一个大障碍。因此,在实践中,如果您有某个对象的任何最终字段,您可能会获得所有这些字段的可见性。

现在,从理论上讲,有人可以编写一个不以这种方式实现的编译器。事实上,许多人经常谈论通过编写最恶意的编译器来测试代码。这在 C++ 人员中尤其常见,他们的语言中有很多未定义的角落,可能会导致可怕的错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

测试最终字段的初始化安全性 的相关文章

随机推荐

  • 通过鼠标滚轮按下事件在网站上滚动了多少像素?

    我正在编写一个自定义滚动条并正在捕捉mousewheel事件 我使用它来调整我想要滚动的元素的scrollTop 向下滚动的像素数是否有标准 或者因系统而异 我在最新版本的 Firefox 中显示 114px 许多鼠标驱动程序允许您设置鼠标
  • UML 中的组合

    在 UML 图中考虑组合时 我们应该在逻辑或实现意义上使用它 这两个术语的示例 实施 机场将包含对国家 地区的引用 换句话说 一个国家是机场的一部分 逻辑 一个国家可以有零个或多个机场 换句话说 机场是国家的一部分 从上图中 哪种情况显示了
  • 使用 Google Apps 脚本,如何替换 Google 表格模板中的文本以制作新表格?

    我有一个谷歌表格 https docs google com spreadsheets d 17qtLpnFTiMoE6blELSTQhtxkWa1hjjzI PcaY 3cS1Q edit resourcekey null gid 465
  • 如何创建每 24 小时运行一次的活动?

    我需要每 24 小时运行一次 delete tags from tags left join tagowners on tags id tagowners tagId where tagowners tagId is null CREATE
  • 在Python中写入具有特定权限的文件

    我正在尝试创建一个仅用户可读和可写的文件 0600 唯一的方法是使用os open 如下 import os fd os open path to file os O WRONLY 0o600 myFileObject os fdopen
  • C 中枚举类型溢出?

    如果我有一个枚举类型 例如 enum week sunday 0 monday tuesday wednesday thursday friday saturday 我有 enum week day day saturday day 一天的
  • 从 Java 访问 Kotlin 类对象

    我有一个 Kotlin 类 它有一个类对象 例如 public class Foo public class object public val SomeValue Int 0 如果我从 Java 使用此类 如何访问类对象内的 SomeVa
  • postgres:从命令行在数据库中创建表

    我试图在 postgres 中创建一个表 但它最终出现在错误的数据库中 这就是我所做的 首先在我的 sql 脚本中创建一个用户和一个数据库 然后创建一个表 代码会解释更多 drop database if exists sinfonifry
  • 如何计算 django 连接表中对象的数量?

    我的问题很简单 我有Users谁拥有Assets or Assets属于用户的如果您愿意 但我无法检索其数量 计数 Assets each User有 我知道这对你们大多数人来说可能听起来很愚蠢 但我是 python django 来自 P
  • 浏览器在使用 CSS 缩放图像时通常使用什么算法?

    我想得到canvas以与 CSS 相同的视觉保真度渲染缩放图像 根据我的测试 在 Chrome 版本 43 0 2357 130 中完成 它似乎不是 Lanczos3 即使我的测试重采样范围 http entropymine com res
  • Java从受限层调用方法

    我什至不确定这是否可行 但我想询问社区的总体意见 我必须解决以下问题 我的项目有 2 层 一个核心层和一个业务层 该核心层提供业务层 这时候Business类就可以导入Core类 为所欲为了 核心类只能导入核心类并使用其方法 禁止访问业务类
  • Zend Framework 2 SOAP AutoDiscover 和复杂类型

    我正在准备 SOAP 服务器并使用以下代码生成 WSDL Controller action code if key exists wsdl params autodiscover new AutoDiscover autodiscover
  • getline 函数的多个分隔符,C++ [重复]

    这个问题在这里已经有答案了 我想逐字阅读文本 以简单的方式避免任何非字母数字字符 从带有空格和 n 的文本 进化 之后 我需要解决这个问题 以防还有 例如 第一种情况只需使用带有分隔符 的 getline 即可解决 我想知道是否有办法使用g
  • React redux api 每 x 秒轮询一次

    我已经做到了这一点 但我正在寻求一种更 最佳实践的方法 它使用https icanhazdadjoke https icanhazdadjokeapi 显示一个随机笑话 每 x 秒更新一次 有更好的方法吗 最终我想添加停止 启动 重置功能
  • Java Web 应用程序的关闭钩子

    我需要在 java web 应用程序停止或 tomcat 停止时保存一些数据 如何才能做到这一点 编辑 如果我使用 jvm shutdown hook 有什么缺点吗 使用一个实现的类ServletContextListener https
  • 为什么需要将新事件添加到 IDL 接口的*末尾*?

    我发现 当我向现有 COM IDL 接口添加新事件时 有时会遇到奇怪的问题 除非将它们添加到接口的末尾 例如 假设我有以下界面 interface IMyEvents HRESULT FooCallback in long MyParam1
  • 在 Elixir 中缓存昂贵的计算

    我在 Elixir 中有一个 Web 应用程序 如下所示 defmodule Test do use Plug Router plug match plug dispatch def expensiveComputation do perf
  • 如何在Carbon实例中添加CarbonInterval实例

    我有一个碳实例 a Carbon Carbon now Carbon Carbon date 2018 06 11 10 00 00 timezone type 3 timezone Europe Vienna 和一个 CarbonInte
  • Parse Server - 如何使用调度程序一遍又一遍地运行“作业”

    我花了一整天的时间尝试让某种调度程序与我的 Parse Server 在 AWS Beanstalk Node js 上运行 一起使用 我能够在 js 文件中获取一些代码 但它似乎不起作用 有什么方法可以设置某种调度程序 这样我就不必通过仪
  • 测试最终字段的初始化安全性

    我试图简单地测试 JLS 保证的最终字段的初始化安全性 这是为了我正在写的一篇论文 但是 根据我当前的代码 我无法让它 失败 有人可以告诉我我做错了什么 或者这只是我必须一遍又一遍地运行然后在一些不幸的时机看到失败的事情吗 这是我的代码 p