数据初始化和整个数据的缓存映射在Java中定期刷新

Xie*_*ezi 5 java guava

我需要在我的Java代码中使用缓存的映射.地图从DB加载,需要定期从DB重新加载(对于地图中的所有数据).因为我们现在无法导入任何新包.谷歌的guava包或代码示例中是否存在任何现有功能?

如果将地图实现为线程安全的话会更好.但如果它不够简单,它仍然可以.

"LoadingCache"是我喜欢的,但它没有数据初始化方法让我在开始时将数据放入地图.并且它需要在地图到期后每次"获取"时到达数据库.

谢谢!


一些示例代码可能会有所帮助:

public interface AToBMapper
{

    public static final String DEFAULT_B_NAME = "DEFAULT";

    public String getBForA(final String a);
}

public class AToBMapperImpl implements AToBMapper
{
    private final SomeDAO dao;

    private Map<String, String> cachedMap;

    public AToBMapperImpl(final SomeDAO dao)
    {
        this.dao = dao;
        cachedMap = new HashMap<String, String>();
    }

    public String getBForA(final String a)
    {
        // if the map is not initialized, initialize it with the data
        // if the map is expired, refresh all the data in the map
        // return the mapped B for A (if there is no mapping for A, return the "DEFAULT")
    }

    private Map<String, String> getTheData(final List<String> listOfB)
    {
        Map<String, String> newData = dao.getAToBMapping(listOfB);
    }
}
Run Code Online (Sandbox Code Playgroud)

Xae*_*ess 2

“LoadingCache”是我喜欢的,但它没有数据初始化方法供我在开始时将数据放入地图中。

当然它确实有这样的方法——putAll(Map<K, V>)来自扩展Cache的接口LoadingCache。该方法将指定映射中的所有映射复制到缓存中

您还put(K, V)可以使用类似的方法来实现此目的。

编辑:

根据您的评论,我可以看出您LoadingCache根本不想要,而是自己维护所有条目的到期时间。以下是您可以使用的简单示例(仅限 JDK 和 Guava 的类):

public class AToBMapperImpl implements AToBMapper {
  public static final long EXPIRE_TIME_IN_SECONDS =
      TimeUnit.SECONDS.convert(1, TimeUnit.HOURS); // or whatever
  private final SomeDAO dao;
  private final ConcurrentMap<String, String> cache;
  private final Stopwatch stopwatch;

  public AToBMapperImpl(SomeDAO dao) {
    this.dao = dao;
    stopwatch = new Stopwatch();
    cache = new MapMaker().concurrencyLevel(2).makeMap();
  }

  @Override
  public synchronized String getBForA(final String a) {
    // if the map is not initialized, initialize it with the data
    if (!stopwatch.isRunning()) {
      cache.putAll(getNewCacheContents());
      stopwatch.start();
    }

    // if the map is expired, refresh all the data in the map
    if (stopwatch.elapsedTime(TimeUnit.SECONDS) >= EXPIRE_TIME_IN_SECONDS) {
      cache.clear();
      cache.putAll(getNewCacheContents());
      stopwatch.reset();
    }

    // return the mapped String for A
    // (if there is no mapping for A, return the "DEFAULT")
    return cache.containsKey(a) ? cache.get(a) : new String(DEFAULT_B_NAME);
  }

  private Map<String, String> getNewCacheContents() {
    return getTheData(Arrays.asList("keys", "you", "want", "to", "load"));
  }

  private Map<String, String> getTheData(List<String> listOfB) {
    return dao.getAToBMapping(listOfB);
  }
}
Run Code Online (Sandbox Code Playgroud)