本文介绍了Java多线程原子引用赋值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用simeple HashMap实现的缓存。喜欢 -

I have a cache which I implemented using a simeple HashMap. like -

HashMap<String,String> cache = new HashMap<String,String>();

此缓存大部分时间用于从中读取值。我有另一个方法重新加载缓存,在这个方法内部我基本上创建一个新的缓存,然后分配引用。据我所知,对象引用的赋值是Java中的Atomic。

This cache is used most of the time to read values from it. I have another method which reloads the cache and inside of this method I basically create a new cache and then assign the reference. As I understand assignment of object reference is Atomic in Java.

public class myClass {
     private HashMap<String,String> cache = null;
    public void init() {
       refreshCache();
    }
    // this method can be called occasionally to update the cache.
    public void refreshCache() {
        HashMap<String,String> newcache = new HashMap<String,String>();
       // code to fill up the new cache
       // and then finally
       cache = newcache; //assign the old cache to the new one in Atomic way
    }
}

我明白如果我没有将缓存声明为volatile,其他线程将无法看到更改,但对于我的用例来说,将缓存中的更改传播到其他线程并且它们可以继续使用它并不是时间关键旧缓存延长时间。

I understand that if I do not declare cache as volatile, other threads will not be able to see the changes but it is not time critical for my use case to propagate the change in cache to other threads and they can continue to work with old cache for extended time.

您是否看到任何线程问题?考虑到许多线程正在从缓存中读取,并且有时只重新加载缓存。

Do you see any threading issue? Consider that many threads are reading from the cache and only at times the cache is reloaded.

编辑 -
我的主要困惑是我不必使用AtomicReference在这里,赋值操作本身是原子的?

EDIT-My main confusion is I do not have to use AtomicReference here as the assignment operation itself is atomic?

编辑 -
我明白为了使顺序正确,我应该将缓存标记为volatile。
但是如果refreshCache方法被标记为synchronized,我不必将缓存设置为volatile,因为Synchronized块将负责排序以及可见性吗?

EDIT -I understand that to make the ordering proper, I should mark cache as volatile.But If refreshCache method is marked as synchronized, I do not have to make cache as volatile, as Synchronized block will take care of ordering as well as visibility?

推荐答案

没有适当的内存障碍,安全。

It is not safe without a proper memory barrier.

有人会认为在填充缓存的步骤之后会发生缓存(cache = newCache)。但是,其他线程可能会遭受这些语句的重新排序,因此分配可能在填充缓存之前发生。因此,可以在完全构造之前获取新缓存,甚至可以看到ConcurrentModificationException。

One would think that the assignment of cache (cache = newCache) would happen after the steps to populate the cache. However, other threads may suffer from reordering of these statements so that the assignment may appear to happen before populating the cache. Thus, it is possible to grab the new cache before it's fully constructed or even worse see a ConcurrentModificationException.

您需要强制执行before-before关系以防止此重新排序,并将缓存声明为volatile将实现这一点。

You need to enforce the happens-before relationship to prevent this reordering, and declaring the cache as volatile would achieve that.

这篇关于Java多线程原子引用赋值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 19:10