【问题标题】:java cache hashmap expire dailyjava缓存hashmap每天过期
【发布时间】:2011-12-06 22:43:26
【问题描述】:

我想要一个HashMap<String, String>,这样每天午夜,缓存就会过期。

请注意,它是 J2EE 解决方案,因此多个线程可以访问它。

在 Java 中实现它的最佳方式是什么?

【问题讨论】:

    标签: java caching monitoring lazy-evaluation


    【解决方案1】:

    虽然其他建议可以用来计算到期时间,但需要注意的是:

    hashmap 的过期可以延迟完成

    即没有任何监控线程!

    实现过期的最简单方法如下:

    1) 扩展哈希映射,并创建一个本地nextMidtime(Long)变量,在构造函数中初始化为System.currentTime....。这将设置为等于下一个午夜时间,以毫秒为单位...

    2) 将以下 sn-p 添加到“containsKey”和“get”方法(或任何其他负责确保数据不会过时的方法)的第一行如下:

    if (currentTime> nextMidTime)
          this.clear();
          //Lets assume there is a getNextMidnight method which tells us the nearest midnight time after a given time stamp.  
          nextMidTime=getNextMidnight(System.currentTimeInMilliseconds);
    

    【讨论】:

    • 我还需要像这样声明哈希图吗: MapcampaignToImg = Collections.synchronizedMap(new HashMap());使用 syncrhonizedMap?
    • 谢谢!我实际上使用 JODA 进行时间处理: DateTime date = new DateTime().toDateMidnight().toDateTime();明天的日期时间 = date.plusDays(1); nextMidtime = 明天.getMillis();
    • 酷 - 很高兴这有效。同步的地图声明不会受到伤害....它将清理您的代码,因此您不必担心点同步。
    • 关于扩展:我希望您可以扩展同步地图方法返回的任何内容。
    【解决方案2】:

    您希望哈希图中的每一件事都在午夜刷新?

    如果是这样,我想我会创建一个新的哈希图并将其替换为原始哈希图。由于替换是在一个步骤中完成的,并且没有其他东西试图进行相同的更改,我相信它应该是线程安全的。

    任何处于中间访问权限的内容都将被允许完成其访问权限。这假定没有其他任何东西持有对此哈希图的引用。

    如果没有将对 hasmap 的引用合并到一个位置,那么我猜 hashmap.clear() 是您最好的选择,如果 hashmap 是同步的。

    如果 hashmap 不同步,那么您只能从单个线程修改它,对吗?让那个线程调用hashmap.clear()

    我认为这涵盖了所有情况。

    【讨论】:

    • 是的,我希望所有的东西都在午夜冲洗干净。你能提供代码示例吗?我没有从答案中弄清楚
    • 如果你的 hashmap 被命名为“cache”,那么安全清除它的代码就是“cache=new HashMap();”
    【解决方案3】:

    您还可以考虑使用 Guava 的 CacheBuilder,它允许您创建其 Cache 接口的自定义实例。在其他有用的功能中,CacheBuilder 允许您根据自己的目的设置定时到期等。

    编辑:我应该注意,您根据last accesslast write 设置条目的过期时间,所以这个建议不完全符合您的要求,即每晚冲洗一次。如果可以选择使用第三方 API,您可能仍会考虑更改您的设计。 Guava 是一个非常聪明的库恕我直言,而不仅仅是用于缓存。

    【讨论】:

      【解决方案4】:

      java.util.Timerjava.util.TimerTask 可能会很有用。

      创建一个可以清除或重新创建HashMapTimerTask,并通过Timer 实例安排它在午夜执行。

      例如:

      // Public single shared hash map.
      static Map<String, String> cached_map_ = new HashMap<String, String>();
      
      public class Hash_map_resetter
          extends TimerTask
      {
          // Constructor takes reference to containing
          // Timer so it can reset itself after execution.
          Hash_map_resetter(Timer a_timer) { timer_ = a_timer; }
      
          // Clear cache.
          public void run()
          {
              cached_map_ = new HashMap<String, String>();
              System.out.println("Cached cleared");
              timer_.schedule(new Hash_map_resetter(timer_), 100);
          }
      
          // Reference to containing Timer.
          private final Timer timer_;
      }
      
      // Example initiation.
      Timer t = new Timer();
      t.schedule(new Hash_map_resetter(t), 100);
      

      该示例只是每 100 毫秒重置一次。 有很多 Timer.schedule() 方法,有些采用 Date 并允许您指定午夜。

      【讨论】:

      • 在哪里启动计时器?在哪个班?
      • @Odelya,唯一的要求是它可以访问您希望重置的HashMap,这样您就可以在包含HashMap 的类中定义一个嵌套类并启动计时器在外部类的构造函数中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 2020-08-20
      • 2012-02-09
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多