Java 使用Enum&;垃圾收集的影响

Java 使用Enum&;垃圾收集的影响,java,enums,garbage-collection,Java,Enums,Garbage Collection,我正在尝试实现一个内存缓存 缓存在启动期间填充,枚举内的映射可以在应用程序生命周期内的任何时间更新 垃圾收集对此实现有什么影响?由于enum类似于一个静态类,我假设只创建了map对象的一个实例,并且该map的内容不会被垃圾收集 我们已经看到,有时这个映射中的键会丢失,这可能是因为GC吗 每当调用检索此缓存时,我们都会返回一个新映射 public enum EmployeeCache { INSTANCE; private Map<String,Map<

我正在尝试实现一个内存缓存

缓存在启动期间填充,枚举内的映射可以在应用程序生命周期内的任何时间更新

垃圾收集对此实现有什么影响?由于enum类似于一个静态类,我假设只创建了map对象的一个实例,并且该map的内容不会被垃圾收集

我们已经看到,有时这个映射中的键会丢失,这可能是因为GC吗

每当调用检索此缓存时,我们都会返回一个新映射

public enum  EmployeeCache {
        INSTANCE;
        private Map<String,Map<String, Employee>> employeeCacheMap = new ConcurrentHashMap<>();
    
        public void populateEmployeeCache(String tenantId,Map<String, Employee> inputEmployeeCacheMap){
            Map<String, Employee> localEmployeeCacheMap = new ConcurrentHashMap<>(inputEmployeeCacheMap);
            employeeCacheMap.put(tenantId,localEmployeeCacheMap);
        }
    
        public Map<String, Employee> getEmployeeCacheMap(String tenantId){
            Map<String,Employee> localMap = new HashMap<>();
            if(employeeCacheMap.get(tenantId) != null) {
                localMap.putAll(employeeCacheMap.get(tenantId));
            }
            return localMap;
        }
    
        public Employee getEmployeeInfo(String tenantId,String Employee){
            return employeeCacheMap.get(tenantId).get(Employee);
        }
    }
public enum EmployeeCache{
实例;
私有映射employeeCacheMap=新的ConcurrentHashMap();
public void populateEmployeeCache(字符串tenantId,映射inputEmployeeCacheMap){
Map localEmployeeCacheMap=新的ConcurrentHashMap(inputEmployeeCacheMap);
put(tenantId,localEmployeeCacheMap);
}
公共映射getEmployeeCacheMap(字符串tenantId){
Map localMap=newhashmap();
if(employeeCacheMap.get(tenantId)!=null){
localMap.putAll(employeeCacheMap.get(tenantId));
}
返回localMap;
}
public Employee getEmployeeInfo(字符串tenantId,字符串Employee){
返回employeeCacheMap.get(tenantId.get(Employee);
}
}

那么为什么不创建一个单例类并在其中存储缓存呢?这是一个基于枚举的单例类。从我看到的代码来看,你有种族
ThreadA
调用
getEmployeeInfo
,执行
employeeCacheMap.get(tenantId)
,但尚未执行
get(Employee)
ThreadB
使用相同的
tenantId
调用
populateEmployeeCache
,并更新映射<代码>线程a在已更改的
映射上执行
获取(员工)
。使用嵌套的
ConcurrentHashMap
s不会立即使代码线程安全。是的。我同意可能存在不一致,但不确定如何从映射中删除关键点。@unnik首先,修复线程安全性,这可能是问题的原因。那么为什么不创建一个单例类并将缓存存储在其中呢?这是一个基于枚举的单例类。从我看到的代码来看,你有种族
ThreadA
调用
getEmployeeInfo
,执行
employeeCacheMap.get(tenantId)
,但尚未执行
get(Employee)
ThreadB
使用相同的
tenantId
调用
populateEmployeeCache
,并更新映射<代码>线程a在已更改的
映射上执行
获取(员工)
。使用嵌套的
ConcurrentHashMap
s不会立即使代码线程安全。是的。我同意可能存在不一致,但不确定如何从地图中删除关键点。@unnik首先,修复线程安全性,这可能是问题的原因。