java - 同时重新加载具有并发读取器的多个缓存

标签 java multithreading caching concurrency

我使用多个 HashMap 将引用数据存储在类中

Map map1;
Map map2;
Map map3;

它们被多个读者同时访问。我想同时重新初始化它们。 如果它是一张 map ,我就可以这样做

public void reload(){
    map1 = createNewMapWithLatestData();
}

由于现有读者拥有旧的引用资料,而新读者则获得新的引用资料,因此效果很好。但由于我有多个 map ,新读者可能会获得最新版本的 map1map2,但会获得旧版本的 map3,因为替换操作不是原子的。

好的,所以我需要锁定它,这让我想到了我的问题。除了使用synchronized锁定所有内容之外,还有什么优雅的方法可以做到这一点?

我只在重新加载实际发生时才需要锁,其他时候不需要。 我查看了 java locks(Read write)、Conditions、CyclicBarriers、Countdownlatches 等,但不确定什么是正确的方法。

最佳答案

如果您创建新 map ,那么读者无论如何都需要有一种方法来获取新 map 的引用。因此,不要直接引用mapX,而是保留对保存所有 map 的对象的引用。当您只需分配新对象的引用时,就可以原子地替换它,就像您在示例中所做的那样。您将在每个地方都有holder.map1,而不是使用map1。

class Holder {
    Map map1;
    Map map2;
}

class Reader {
    Holder holder;
    void read() {
        writer.getHolder().map1.get("x");
    }
}

class Writer {
    Holder holder;
    Holder getHolder() {
        return holder;
    }
    void reload() {
        Holder newHolder = new Holder();
        newHolder.map1 = createNewMap1WithLatestData();
        newHolder.map2 = createNewMap2WithLatestData();
        holder = newHolder; // this is atomic
    }
}

关于java - 同时重新加载具有并发读取器的多个缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35210943/

相关文章:

java - 在 Hadoop 分布式缓存中创建和放置文件

java - Oracle中如何同时更新两个表?

c# - MailKit:尝试在 ASP.NET Core 中实现 IMAP 客户端以接收新邮件事件

multithreading - Ada任务和终止

python - 如何禁用 Flask-Cache 缓存

Azure Verizon CDN - 100% 缓存 CONFIG_NOCACHE

java - 为什么我不能在我的 IntelliJ 中下载 OpenJDK-17?

java - 无法计算包含两个 arrayllist 的 arraylist 的大小

java - Java 中复制数组的这些方法有什么区别?

c# - BackgroundWorker 和 System.Threading.Thread 之间的区别