java - 在java中同时使多个worker的缓存无效而不影响性能

标签 java caching concurrency linkedhashmap

我正在创建自己的缓存对象,它将为多个线程提供服务,这是一项任务,因此我不允许使用现有的包和 jar。我正在尝试找出如何同时使它们全部无效。 我有一个包含一堆条目的日期结构,其中键是整数,值是 boolean 值。当工作线程未命中时,会将值添加到其缓存中。 我有几个其他线程更新此数据结构,一旦它们更新它,它们就应该使具有此缓存的所有其他工作线程无效,前提是它们的缓存中有此条目。

例如 说有两个 worker T1缓存有1,true T2缓存有3个,true

数据结构有1,true; 2、真实; 3 真实。现在更新程序更改为 3, false。因此它应该检查 T1 并且不执行任何操作,并且应该检查 T2 并更改它。然而,这两项检查应该以某种方式同时发生,因为如果我有这样的情况 T1缓存有3个,true T2缓存有3个,true T1 可能已失效,而 T2 尚未失效,我们的行为不一致。

有什么想法吗? 我的缓存代码是

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

public class workerCache {
    @SuppressWarnings("rawtypes")
    LinkedHashMap cache;
    ReentrantLock lock;

    @SuppressWarnings("serial")
    public <T> workerCache(final int maxEntries) {
        this.lock = new ReentrantLock();

        this.cache = new LinkedHashMap<T, T>(maxEntries + 1) {
            @SuppressWarnings("rawtypes")
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return size() > maxEntries;
            }
        };
    }

    @SuppressWarnings("unchecked")
    public <T> void setEntry(T key, T value) {

        lock.lock();
        try {
            cache.put(key, value);
        } finally {
            lock.unlock();
        }
    }

    public <T> void invalidateEntry(T key) {
        lock.lock();
        try {
            cache.remove(key);
        } finally {
            lock.unlock();
        }

    }

    @SuppressWarnings("unchecked")
    public <T> T get(T key) {
        lock.lock();
        try {
            return (T) this.cache.get(key);
        } finally {
            lock.unlock();
        }
    }

最佳答案

听起来您正在想象三个线程“T1”、“T2”、“T3”都有自己的 workerCache 副本,它们需要保持同步。这是正确的吗?

如果是这样,我会说这是一个问题。不是三个缓存(每个线程一个),而是在所有线程之间共享一个缓存怎么样?

这样,每个人都可以一直看到相同的数据,因为只有一份数据副本(因为只有一个缓存)。如果您使 T1 中的条目无效,那么每个人都会同时“看到”该无效 - 这是因为只有一个缓存。

如果您有三个线程都更新相同的 key ,则最后一个进入缓存的线程获胜。我不确定这对您来说是否是一个问题。

我有解决这个问题的地方吗?

关于java - 在java中同时使多个worker的缓存无效而不影响性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23611085/

相关文章:

swift - 使@MainActor 类或 Actor 符合 Codable

java - 将 "/"站点迁移到 Java EE 打包时处理上下文路径引用

jvm - 任意 JVM 行为

caching - 动态改变 Magento 的 adminhtml 菜单选项

spring - 在 Spring Boot 应用程序启动时清除 Redis 缓存

MySQL 缓存一切

python - concurrent.futures.as_completed 是如何工作的?

C++ 终端应用程序并发输入和输出

java - 检查 UUID 字符串是否为素数

java - Embeddable 和 EmbeddedId 之间的 JPA 映射 @ManyToOne