2010-11-01 110 views
1

许多人将ConcurrentMap作为缓存来引用。可以/我应该使用ConcurrentMap和我自己的缓存吗?

这是个好主意,这样做:

public List<Task> listTasks(final ProcessDefinition def, final boolean filterEnumerated) { 
    final String CACHENAME = def.getName() + "-v" + def.getVersion() + "-Tasks"; 
    ConcurrentMap<String, List<Task>> cache = (ConcurrentMap<String, List<Task>>) Contexts.getApplicationContext().get(CACHENAME); 
    if (Contexts.getApplicationContext().isSet(CACHENAME) && cache != null) { 
     return cache.get(CACHENAME); 
    } else { 

     ConcurrentMap<String, List<Task>> myTasks = new MapMaker() 
      .softValues() 
      .expiration(2L, TimeUnit.HOURS) 
      .makeComputingMap(
       new Function<String, List<Task>>() { 
       @Override 
       public List<Task> apply(String from) { 
        return getTasksFromDefinition(def, filterEnumerated); 
       } 
       }); 

     myTasks.put(CACHENAME, getTasksFromDefinition(def, filterEnumerated)); 

     Contexts.getApplicationContext().set(CACHENAME,myTasks); 
     Collection<List<Task>> tz = myTasks.values(); 
     //First element in the collection 
     return new ArrayList<Task>(tz.iterator().next()); 
    } 
} 

或者是不是必须使用的ApplicationContext(它是Java-EE应用程序上下文)也缓存地图,只检索来自地图的价值?
对这个post

答案类似此外,我想知道,.expiration(2L, TimeUnit.HOURS)。这真的是2小时,还是长时间取毫秒值?

+0

请编辑您的问题,说明您正在使用Google收藏夹,它会帮助人们回答(是的,我知道您将其标记为这样):-) – 2010-11-01 15:17:13

+0

我不同意。如果您不使用MapMaker,我相信这个问题仍然有效。它仍然是一个'ConcurrentMap' – 2010-11-01 16:56:41

回答

2

我个人认为在ApplicationContext中存储这样的缓存是好的,因为它是线程安全的。但请注意缓存的大小,尤其是在群集等情况下。

在过期问题上,过期为2小时,如您所期望的。

相关问题