gpt4 book ai didi

java - java8中使用volatile实现Acquire/Release模型

转载 作者:行者123 更新时间:2023-12-03 20:23:34 25 4
gpt4 key购买 nike

就我而言,我想实现 Acquire/Release java8 中的模型与 volatile .
所以我编写了使用 volatile 共享变量 I 的代码保证MAP的修改可以被其他线程看到。

public static volatile int I = 0;

public static final Map<String, String> MAP = new HashMap<>();

// run at Thread-1
public static void write(){
MAP.put("test", "test");
I++; // release
}

// run at Thead-2
public static void read(){
int i = I; // acquire
MAP.get("test"); // want to see the modifying by write()
}
我的问题是:
  • 代码同步是否正确?
  • JIT有没有可能消除未使用的局部变量i使acquire操作无效?
  • 最佳答案

    首先注意++volatile变量是 不是原子的 ,因此,在多次更新的情况下,您不能依赖它的值。
    只要只有一个更新,检查更新是否确实发生就足够了,但执行检查至关重要。否则,无法保证(应该获得) volatile 读取是在(应该是释放) volatile 更新之后。
    只需考虑以下时间:

          Thread 1        Thread 2

    ┌ ┐ [ Read I ]
    │ map update │ ┌ ┐
    └ ┘ │ map query │
    [ Write I ] └ ┘
    在这里,两个线程同时使用映射,这是无可救药的破坏,而获取和释放操作没有任何后果,因为获取不是在释放之后。
    如果您检查已读取的值,并且仅当它是另一个线程写入的预期值时才继续,则您只能依赖这种关系。

    由于整个构造仅适用于单个更新,因此您可以使用 boolean反而:
    private static volatile boolean I = false;

    private static final Map<String, String> MAP = new HashMap<>();

    // run at Thread-1
    public static void write(){
    MAP.put("test", "test");
    I = true; // release
    }

    // run at Thead-2
    public static void read(){
    if(I) { // acquire
    MAP.get("test"); // want to see the modifying by write()
    }
    }
    您不能将其用于多次更新,因为想要执行第二次更新的线程必须确保在第一次更新后读取 map 的所有线程完成之前不开始更新 map 。但是使用这种方法根本无法获得此信息。

    关于java - java8中使用volatile实现Acquire/Release模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65951795/

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