ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java缓存超时

2019-11-27 17:02:00  阅读:417  来源: 互联网

标签:caching nonblocking java


我们有一个简单但非常常用的缓存,由ConcurrentHashMap实现.现在,我们要定期刷新所有值(例如,每15分钟刷新一次).

我想要这样的代码:

 private void regularCacheCleanup() {
        final long now = System.currentTimeMillis();
        final long delta = now - cacheCleanupLastTime;
        if (delta < 0 || delta > 15 * 60 * 1000) {
            cacheCleanupLastTime = now;
            clearCache();
        }
  }

除了应该是:

>线程安全
>非阻塞且性能卓越,如果不打算清除缓存
>除了java.*类以外没有依赖项(因此没有Google CacheBuilder)
>坚如磐石;-)
>无法启动新线程

现在,我想在ThreadLocal中实现一个短计时器.到期后,将以同步方式检查实际计时器.但是,这是很多代码,所以一个更简单的主意会很好.

解决方法:

解决此问题的主流方法是使用一些计时器线程按指定的时间间隔刷新缓存.但是,由于不需要创建新线程,因此我可以想到的一种可能的实现是伪定时缓存刷新.基本上,我会在缓存访问器(put和get方法)中插入检查,并且每次客户端每次使用此方法时,我都会在执行put或get操作之前检查是否需要刷新缓存.这是一个大概的想法:

class YourCache {

  // holds the last time the cache has been refreshed in millis
  private volatile long lastRefreshDate;

  // indicates that cache is currently refreshing entries
  private volatile boolean cacheCurrentlyRefreshing;

  private Map cache = // Your concurrent map cache...

  public void put(Object key, Object element) {
    if (cacheNeedsRefresh()) {
      refresh();
    }
    map.put(key, element);
  }

  public Object get(Object key) {
    if (cacheNeedsRefresh()) {
      refresh();
    }
    return map.get(key);
  }

  private boolean cacheNeedsRefresh() {
    // make sure that cache is not currently being refreshed by some
    // other thread.
    if (cacheCurrentlyRefreshing) {
      return false;
    }
    return (now - lastRefreshDate) >= REFRESH_INTERVAL;
  } 

  private void refresh() {
    // make sure the cache did not start refreshing between cacheNeedsRefresh()
    // and refresh() by some other thread.
    if (cacheCurrentlyRefreshing) {
      return;
    }

    // signal to other threads that cache is currently being refreshed.
    cacheCurrentlyRefreshing = true;

    try {
      // refresh your cache contents here
    } finally {
       // set the lastRefreshDate and signal that cache has finished
       // refreshing to other threads.
       lastRefreshDate = System.currentTimeMillis();
       cahceCurrentlyRefreshing = false;
    }
  }
}

就我个人而言,我不会考虑这样做,但是如果您不想或无法创建计时器线程,那么这可能是您的选择.

请注意,尽管此实现避免了锁定,但由于竞赛事件,它仍然易于重复刷新.如果可以满足您的要求,那应该没问题.但是,如果您有更严格的要求,则需要放置锁定以正确同步线程并避免争用事件.

标签:caching,nonblocking,java
来源: https://codeday.me/bug/20191127/2075771.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有