当前位置: 首页 > 面试题库 >

Java多线程原子引用分配

邴越彬
2023-03-14
问题内容

我有一个缓存,该缓存是使用Simeple HashMap实现的。喜欢 -

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

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

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
    }
}

我了解,如果我不将缓存声明为易失性,则其他线程将无法看到更改,但是对于我的用例而言,将缓存中的更改传播到其他线程不是时间紧迫的,它们可以继续使用旧缓存延长时间。

您看到任何线程问题吗?考虑到许多线程正在从高速缓存中读取数据,并且仅在重新加载高速缓存时才读取。

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

编辑-
我知道要使排序正确,我应该将缓存标记为易失性。但是,如果将refreshCache方法标记为已同步,则不必使高速缓存为易失性,因为已同步块将同时处理顺序和可见性?


问题答案:

它是 不是 安全的没有一个适当的内存屏障。

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

您需要强制执行before-before关系,以防止这种重新排序,并且将缓存声明为易失性即可实现这一点。



 类似资料:
  • 我只是一个非开发人员,所以我的问题可能非常简单! 我只是在测试Java多线程的东西,这不是真正的代码。我想知道如何在 Java 中同时更新两个成员变量,以防我们希望它们都同步。举个例子: 在这种情况下(当然,想象一下多线程),我希望能够保证对< code>items和< code>itemToStatus的任何读取总是返回相同的结果。 因此,如果代码在< code>itemToStatus.put

  • 问题内容: 最近,我正在阅读一个教程,其中遇到了一条声明: “Java语言规范保证了读取或写入的变量是一个原子操作(除非该变量的类型的或)类型的操作变量或者是只有当它们与申报原子的关键字。” 或提供类似的方法,并且其是原子的。 我对以上声明感到有些困惑。.请您澄清一下 何时使用 或 使用类。 问题答案: 否则(与作为一个)是一个原子操作。但是执行操作不是原子操作,因为它需要读取a的值,递增和写入a

  • 1. 并发编程概念 原子性 一个操作不能被再拆分了;即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。一个很经典的例子就是银行账户转账问题。 增量操作符++,不是原子的操作,它是先读取旧值,然后写回新值,包含2个操作 可见性 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 有序性 即程序执行的顺序按照代码的先后

  • 原子操作是否足够安全,可以在多线程应用程序中使用它,而不会导致竞争条件和其他并发问题?假设我们不担心可见性(我们从CPU读取/写入所有内容)。

  • 这是一个关于Java中多线程的初学者问题。 根据我的理解,当创建多个(用户)线程来运行程序或应用程序时,就没有父线程和子线程的概念。它们都是独立的用户线程。 因此,如果主线程完成执行,那么另一个线程(Thread2)仍将继续执行,因为在Thread2的执行线程完成之前,它不会被JVM杀死(https://docs.oracle.com/javase/6/docs/api/java/lang/Thr

  • 本文向大家介绍Java 多线程使用要点分析,包括了Java 多线程使用要点分析的使用技巧和注意事项,需要的朋友参考一下 多线程细节问题 sleep方法和wait方法的异同点? 相同点: 让线程处于冻结状态. 不同点: sleep必须指定时间 wait可以指定时间也可以不指定时间 sleep时间到,线程处于临时阻塞状态或者运行态 wait如果没有时间,必须通过notify或者notifyAll唤醒