易失性hashmap的特征

Big*_*c66 6 java multithreading volatile

我试图牢固地处理一个变量如何声明为

private volatile HashMap<Object, ArrayList<String>> data;
Run Code Online (Sandbox Code Playgroud)

会表现在多线程环境中.

我理解的是,这volatile意味着从主内存而不是从线程缓存中获取.这意味着如果正在更新变量,我将不会看到新值,直到更新完成并且我不会阻止,而是我看到的是最后更新的值.(这正是我想要的BTW.)

我的问题是,当ArrayList<String>线程B正在读取时,我在线程A中检索并添加或删除字符串时,volatile关键字究竟会受到什么影响?的HashMap唯一的或延伸到内容(K和V)的效果HashMap,以及?也就是说,当线程B获得ArrayList<String>当前正在线程A中修改的内容时,实际返回的内容是ArrayList<String>更新开始之前存在的最后一个值.

为了清楚起见,我们假设更新正在添加2个字符串.当线程B获得数组时,线程A中已添加一个字符串.线程B是否在添加第一个字符串之前获取数组?

dca*_*tro 5

这意味着如果一个变量正在更新,我将不会看到新值,直到更新完成并且我不会阻止,而是我看到的是最后更新的值

这是你的困惑之源.volatile的作用是确保对该字段的读取和写入是原子的 - 因此没有其他线程可以看到部分写入的值.

如果写入操作在写入第一个地址之后和写入第二个地址之前被抢占,则非原子长字段(在32位机器上占用2个存储器地址)可能会被错误地读取.

请注意,对字段的读/写的原子性与更新内部状态无关HashMap.更新an的内部状态HashMap需要多个指令,这些指令不是原子的整体.这就是你使用锁来同步访问权限的原因HashMap.

此外,由于对引用的读/写操作总是原子的,即使该字段未标记为volatile,因此关于原子性,volatile和非易失性HashMap之间没有区别.在这种情况下,所有volatile都会为您提供获取释放语义.这意味着,即使仍然允许处理器和编译器稍微重新排序指令,也不会将指令移到易失性读取之上或低于易失性写入.