是否可以修改非易失性变量,以便另一个线程能够“看到”更新?

2024-02-17

我有一个 Thread-X,它读取非易失性每秒都有变量,这样做不需要任何同步手段。

现在我想知道是否有某种方法可以修改 Thread-Y 上的非易失性变量,以便 Thread-Y 的写入(最终)在 Thread-X 上可见?

public class Test {
    private static boolean double = 1; // this variable is
                                             // strictly not volatile

    public static void main(String args[]) {
        new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while (true) {
                    System.out.println(variable);
                    try {
                        java.lang.Thread.currentThread().sleep(1000);
                    } catch (java.lang.InterruptedException e) {
                    }
                }
            }
        }).start(); // line 17
        new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                // the task is to change variable to "2" such the write
                // is (eventually) registered by the other threads

                // allowed to use any synchronization/locking techniques
                // required, but line 1 to line 17 must not be changed
            }
        }).start();
    }
}

是否可以修改非易失性变量,以便另一个线程无需任何同步技术即可读取它(raw read)最终能够“看到”更新吗?

背景:

我需要从大量线程中读取一个变量,infinite次数。

据我了解(如果我错了,请纠正我),在大多数CPU(例如x86)上,易失性变量的读取是“几乎完全免费”,但不是“完全免费”。

现在既然我有一个infinite读取的次数infinite线程数,我希望变量是非易失性。然而,千载难逢的情况下,变量需要更新。在我的用例中,更新该变量的成本有多高并不重要,但该更新最终必须可由读取器线程读取。

解决方案:

基于托马斯的评论 https://stackoverflow.com/a/9580724/632951,我已经构建了这个解决方案,我想知道 Solution-1 是有缺陷的还是可靠的?

public class Solution1 {
    private static double variable = 1; // this variable is
                                        // strictly not volatile

    public static void main(String args[]) {
        new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while (true) {
                    System.out.println(variable);
                    try {
                        java.lang.Thread.currentThread().sleep(1000);
                    } catch (java.lang.InterruptedException e) {
                    }
                }
            }
        }).start(); // line 17
        new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                variable = 2;
                // writer-thread now terminates,
                // is it guaranteed that when it
                // "terminates successfully", variable
                // is updated on the reader-thread ?
            }
        }).start();
    }
}

基于乔纳斯的评论 https://stackoverflow.com/a/9580686/632951,我已经构建了这个解决方案,我想知道解决方案 2 是有缺陷的还是可靠的?

public class Solution2 {
    private static double variable = 1; // this variable is
                                        // strictly not volatile
    private static volatile boolean lock = false;

    public static void main(String args[]) {
        new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while (true) {
                    System.out.println(variable);
                    try {
                        java.lang.Thread.currentThread().sleep(1000);
                    } catch (java.lang.InterruptedException e) {
                    }
                }
            }
        }).start(); // line 17
        new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                variable = 2;
                lock = false; // does this line guarantee
                                // that other threads will now 
                                // see the update to variable (piggypacking)?

                // now let's assume this thread doesn't terminate
            }
        }).start();
    }
}

是否可以修改非易失性变量,以便另一个在没有任何同步技术(原始读取)的情况下读取该变量的线程最终能够“看到”更新?

No.必须使用某种同步技术,否则(JIT)编译器可以优化您的行以System.out.println(false); (if false是该线程首先看到的值)。也就是说,它可以优化reading变量消失。

我不知道它实际上会这样做的可能性有多大,但根据 Java 内存模型,这是可以的,所以你的选择是:

  • volatile。对于您的情况来说,这可能是最简单、最轻便的选择。
  • AtomicBoolean。关于 it 与 volatile 的一些讨论here https://stackoverflow.com/questions/3786825/java-volatile-boolean-vs-atomicboolean and here https://stackoverflow.com/questions/4876122/volatile-boolean-vs-atomicboolean.
  • synchronized堵塞。在这种情况下就太过分了。
  • java.util.concurrent.locks.Lock。更多功能synchronized.
  • Thread.join()。在这种情况下没有用(读取线程将等待写入器终止)。
  • 捎带。 http://www.javamex.com/tutorials/synchronization_piggyback.shtml想都别想。有太多的事情可能而且将会出错。

只需使用volatile让 JVM 负责高效地实现它。价格不贵。 https://stackoverflow.com/questions/4633866/is-volatile-expensive

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

是否可以修改非易失性变量,以便另一个线程能够“看到”更新? 的相关文章

随机推荐

  • 按钮是否允许显示:网格? [复制]

    这个问题在这里已经有答案了 按钮是否允许显示 网格 或者更一般地说 是否有任何元素不能使用display grid 考虑 button div display grid grid template columns 50px 50px Nev
  • 从 DOS 命令行关闭正在运行的应用程序

    start 命令可以在批处理文件中启动像记事本这样的应用程序 如下所示 start notepad start my love mp3 但是如何从命令行关闭正在运行的应用程序呢 我发现taskkill在我的搜索中 但我认为这不是正确的命令
  • 如何显示当前运行的python模块的路径? [复制]

    这个问题在这里已经有答案了 如何显示当前运行的python模块的路径 哪个会打印 Users user documents python bla py如果 bla py 被放置在 Users user documents python 如果
  • 将二进制格式字符串转换为 int,在 C 中

    如何将二进制字符串 如 010011101 转换为 int 以及如何将 int 如 5 转换为 C 中的字符串 101 The strtol标准库中的函数采用 base 参数 在本例中为 2 int fromBinary const cha
  • S3 上的静态网站,路由为 53 - 无法访问网站

    我在 S3 上托管了一个静态网站 并设置了合适的存储桶策略 在另一个选项卡中查看 端点 效果非常好 此后 我在路线 53 中创建了一个托管区域 为其提供了理想的人类可读地址 创建托管区域后 我新创建的托管区域中有两条记录 其中一条记录属于类
  • Django 根据子级过滤父级

    我有发票型号 class Invoice models Model name models ForeignKey Patient on delete models CASCADE 我有另一个发票金额模型 其中包含发票的 FK class I
  • Firebase 远程通知未收到?

    我尝试通过云消息从 Firebase 控制台发送远程通知 但我的手机没有收到任何警报 我已将证书上传到 Firebase 并且正在使用 Firebase 教程提供的默认代码来接收通知 Here is a picture of my cert
  • tkinter OptionMenu 问题(bug?):GUI 和程序值未保持同步(python 3.x)

    在某些情况下 下面的演示 OpenMenu 小部件上显示的值与程序使用的值不匹配 这会导致当用户期望选项 A 时执行选项 B 导致 WTF 用户的反应 不幸的是 OptionMenu 小部件没有我与其他小部件一起使用来轻松处理问题的 命令
  • 如何在 PostgreSQL 中获得随机笛卡尔积?

    我有两张桌子 custassets and tags 为了生成一些测试数据 我想做一个INSERT INTO一个多对多表SELECT从每个表中获取随机行 以便一个表中的随机主键与第二个表中的随机主键配对 令我惊讶的是 这并不像我最初想象的那
  • aframe 不渲染映射到画布的 Lottie json 纹理,但可以在 Three.js 中使用

    所以我基本上试图通过 aframe 将 json 渲染到画布上 你确实成功地将其映射到 Three js 中的画布上 但是当我尝试在 aframe 中复制它时 它只显示一个白色框架 它显示它在那里 但没有显示动画 无法在 aframe 中渲
  • C# SSIS 数据流组件 - 创建自定义输入列

    我正在尝试创建我的第一个数据流组件 该组件将获取输入地址 通过 PAF api 运行它 并从文件源或数据库表中吐出格式正确的地址和原始输入列 我需要以特定格式提供源输入地址 因此我需要用户将源输入列映射到特定的自定义输入列 我能够使用 in
  • Spring RabbitMQ 教程导致连接被拒绝错误

    我是一名经验丰富的 Java 程序员 并且是第一次尝试 Spring Rabbit MQ 我遵循了 messages rabbitMQ 教程exactly使用 Maven http spring io guides gs messaging
  • 在 Node.js 上强制使用 TLS 1.1 或更高版本

    我正在尝试创建一个使用 TLS 1 1 或更高版本的服务器 这是我当前的 TLS 配置 var options options key fs readFileSync privatekey pem options cert fs readF
  • 如何从旋转矩阵中删除轴?

    我有一个 opengl 任意旋转矩阵 想删除 X 和 Y 轴 只留下 Z 轴 这可能吗 有关如何做的任何指示吗 只是在这里大声思考 但是你不能使用矩阵来旋转像 1 0 0 这样的向量 然后执行 atan2 y x 看看它旋转了多少 然后构建
  • 删除 MySQL 中的重复行

    我有一个包含以下字段的表 id Unique url Unique title company site id 现在 我需要删除具有相同的行title company and site id 一种方法是使用以下 SQL 和脚本 PHP SE
  • 如何创建抑制错误和警告的宏?

    我想重新定义或覆盖其中的一些函数Base 而用户却没有注意到这一点 我不久前发现了这个技巧 original stderr STDERR redirect stderr code redirect stderr original stder
  • 如何从C:\Python37\Scripts创建类似于pip.exe、jupyter.exe等的.exe?

    为了要做pip or jupyter可通过 Windows 命令行获取无论当前工作目录如何只用pip or jupyter Windows上的Python好像用的是这个方法 put C Python37 Scripts在路径中 创建一个 1
  • 如何在 Ajax 后过滤结果上添加 Ajax 分页

    我正在开发一个带有分类过滤器的网站 我创建了这样的分类小部件 Tax A Tax B Tax C Tax D 并在下面放置一个应用过滤器 当我单击 应用过滤器 时 它将通过 Ajax 请求过滤帖子并在 HTML 上附加帖子 现在我想在过滤器
  • HTTP 状态代码 4xx 与 5xx

    我正在创建一个 REST API 发现在某些情况下很难选择要返回的正确 HTTP 状态代码 假设我期望某个值 当它不存在时 我无法执行特定任务并返回错误 由于缺少值 服务器无法处理该请求 但它是客户端发送的 格式良好但不完整 最好返回一个4
  • 是否可以修改非易失性变量,以便另一个线程能够“看到”更新?

    我有一个 Thread X 它读取非易失性每秒都有变量 这样做不需要任何同步手段 现在我想知道是否有某种方法可以修改 Thread Y 上的非易失性变量 以便 Thread Y 的写入 最终 在 Thread X 上可见 public cl