Java 刷新cahche分配线程安全性

Java 刷新cahche分配线程安全性,java,thread-safety,Java,Thread Safety,我有一个如上所示的缓存刷新逻辑,并且喜欢确保它是线程安全的,并且是正确的方式 我有一个后台线程定期调用刷新。包含由多个线程调用 在刷新中,我有cache=newSet。这个线安全吗?如果cache.contains和cache=newSet同时执行,会发生什么情况?后台线程运行刷新时,可能有一个线程正在调用contains 另外,由于contain only call cache.contains函数,我是否需要新的ConcurrentHashSet 在刷新中,我有cache=newSet。这个

我有一个如上所示的缓存刷新逻辑,并且喜欢确保它是线程安全的,并且是正确的方式

我有一个后台线程定期调用刷新。包含由多个线程调用

在刷新中,我有cache=newSet。这个线安全吗?如果cache.contains和cache=newSet同时执行,会发生什么情况?后台线程运行刷新时,可能有一个线程正在调用contains

另外,由于contain only call cache.contains函数,我是否需要新的ConcurrentHashSet

在刷新中,我有cache=newSet。这个线安全吗

它不是100%线程安全的,因为缓存没有用volatile关键字标记。在这种情况下,即使分配是JVM中的一个原子操作,当一个线程访问cache.contains,而另一个线程执行分配刷新时,两个线程都可能无法立即看到更改

因为volatile关键字保证了每当发生更改时多个线程之间共享状态的可见性

另外,由于contain only call cache.contains函数,我是否需要 newConcurrentHashSet

如果任何线程都没有修改缓存,但只读取它,那么也可以使用非并发集。但在这种情况下,需要将缓存变量设置为私有


通过使缓存易失性,cache=newSet线程安全吗?cache.containsnum和cache=newSet可以同时调用,还可以吗?@codereviewansk质疑只有当超过1个线程访问共享可变状态并且至少有1个线程修改它时,才需要同步访问共享可变状态。在这种情况下,赋值后任何线程都不会进行修改。只有重新分配一个全新的集合。不修改现有集合。
public class Test {

    Set<Integer> cache = Sets.newConcurrentHashSet();

    // multiple threads call this
    public boolean contain(int num) {
        return cache.contains(num);
    }

    // background thread periodically calls this
    private void refresh() {
        Set<Integer> newSet = getNums();
        cache = newSet; // is this assignment thread safe?
    }

    private Set<Integer> getNums() {
         Set<Integer> newSet = Sets.newConcurrentHashSet();
         // read numbers from file and add them to newSet
         return newSet;
    }
}
    public class Test {

        private volatile Set<Integer> cache = Sets.newConcurrentHashSet();

        // multiple threads call this
        public boolean contain(int num) {
            return cache.contains(num);
        }

        // background thread periodically calls this
        private void refresh() {
            Set<Integer> newSet = getNums();
            cache = newSet; // is this assignment thread safe?
        }

        private Set<Integer> getNums() {
             Set<Integer> newSet = Sets.newConcurrentHashSet();
             // read numbers from file and add them to newSet
             return newSet;
        }
    }