gpt4 book ai didi

java - 不稳定的 Java 重新排序

转载 作者:行者123 更新时间:2023-12-04 09:17:18 26 4
gpt4 key购买 nike

首先让我说,我知道这是一个相当普遍的话题,但在搜索它时,我找不到另一个可以澄清以下情况的问题。如果这可能是重复的,我很抱歉,但是你去:
我是并发新手,为了回答问题,我得到了以下代码:

  • a)为什么除了“00”之外的任何其他输出都是可能的?
  • b) 如何修改代码以便始终打印“00”。
  •  boolean flag = false;

    void changeVal(int val) {
    if(this.flag){
    return;
    }
    this.initialInt = val;
    this.flag = true;
    }

    int initialInt = 1;

    class MyThread extends Thread {
    public void run(){
    changeVal(0);
    System.out.print(initialInt);
    }
    }

    void execute() throws Exception{
    MyThread t1 = new MyThread();
    MyThread t2 = new MyThread();
    t1.start(); t2.start(); t1.join(); t2.join();
    System.out.println();
    }
    对于 一个 ) 我的回答如下:在没有任何 volatile/同步构造的情况下,编译器可以重新排序一些指令。特别是“this.initialInt = val;”和“this.flag = true;”可以切换,以便发生这种情况:线程都已启动并且 t1 提前收费。给定重新排序的指令,它首先设置 flag = true。现在在它到达“this.initialInt = val;”的最后一条语句之前另一个线程跳进来,检查 if 条件并立即返回,从而打印未更改的 initialInt 值 1。除此之外,我相信如果没有任何 volatile/同步,不确定 t2 是否会看到在 t1 中对 initialInt 执行的分配所以它也可以打印“1”作为默认值。
    对于 b ) 我认为该标志可能会变得不稳定。我了解到,当 t1 写入 volatile 变量设置 flag = true 然后 t2 时,在 if 语句中读取此 volatile 变量时,将看到在 volatile 写入之前执行的任何写操作,因此 initialInt = val 也是。因此,t2 已经看到它的 initialInt 值更改为 0,并且必须始终打印 0。
    但是,这只有在使用 volatile 成功地阻止了我在 a) 中描述的任何重新排序时才有效。我已经阅读了有关 volatile 完成此类事情的信息,但我不确定在没有任何进一步的同步块(synchronized block)或任何此类锁的情况下这是否总是有效。来自 this answer我已经收集到在 volatile 存储(因此 this.flag = true)可以重新排序以使其超出它之前没有发生任何事情。在那种情况下,initialInt = val 不能向下移动,我应该是正确的,对吧?或不 ? :)
    非常感谢你的帮助。我期待着您的回复。

    最佳答案

    此示例将始终打印 00 ,因为您执行 changeVal(0)打印前。
    要模拟可能不打印 00 的情况,您需要移动 initialInt = 1;像这样的线程的上下文:

    class MyThread extends Thread {
    public void run(){
    initialInt = 1;
    changeVal(0);
    System.out.print(initialInt);
    }
    }
    现在你可能有一个竞争条件,它在 thread1 中将 initialInt 设置回 1,然后在 thread2 中打印
    另一种可能导致竞争条件但更难理解的替代方法是切换设置标志和设置值的顺序
    void changeVal(int val) {
    if(this.flag){
    return;
    }
    this.flag = true;
    this.initialInt = val;
    }

    关于java - 不稳定的 Java 重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63162001/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com