最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java緩存Map設(shè)置過(guò)期時(shí)間實(shí)現(xiàn)解析

 更新時(shí)間:2019年12月23日 08:58:09   作者:1024。  
這篇文章主要介紹了Java緩存Map設(shè)置過(guò)期時(shí)間實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了Java緩存Map設(shè)置過(guò)期時(shí)間實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

前言

最近項(xiàng)目需求需要一個(gè)類似于redis可以設(shè)置過(guò)期時(shí)間的K,V存儲(chǔ)方式。項(xiàng)目前期暫時(shí)不引進(jìn)redis,暫時(shí)用java內(nèi)存代替。

解決方案

1. ExpiringMap

功能簡(jiǎn)介 :

1.可設(shè)置Map中的Entry在一段時(shí)間后自動(dòng)過(guò)期。

2.可設(shè)置Map最大容納值,當(dāng)?shù)竭_(dá)Maximum size后,再次插入值會(huì)導(dǎo)致Map中的第一個(gè)值過(guò)期。

3.可添加監(jiān)聽事件,在監(jiān)聽到Entry過(guò)期時(shí)調(diào)度監(jiān)聽函數(shù)。

4.可以設(shè)置懶加載,在調(diào)用get()方法時(shí)創(chuàng)建對(duì)象。

github地址:https://github.com/jhalterman/expiringmap/

maven添加依賴即可使用

<dependency> 
  <groupId>net.jodah</groupId> 
  <artifactId>expiringmap</artifactId> 
  <version>0.5.8</version> 
</dependency> 
public static void main(String[] args) throws InterruptedException {
    ExpiringMap<String,String> map = ExpiringMap.builder()
        .maxSize(100)
        .expiration(1, TimeUnit.SECONDS)
        .expirationPolicy(ExpirationPolicy.ACCESSED)
        .variableExpiration()
        .build();
    map.put("test","test123");
    Thread.sleep(500);
    String test= map.get("test");
    System.err.println(test);
 }

2.Guava - LoadingCache

Google開源出來(lái)的一個(gè)線程安全的本地緩存解決方案。

特點(diǎn):提供緩存回收機(jī)制,監(jiān)控緩存加載/命中情況,靈活強(qiáng)大的功能,簡(jiǎn)單易上手的api

但是該cache不會(huì)在特定時(shí)間準(zhǔn)時(shí)回收鍵值,所以不適用于我當(dāng)前的業(yè)務(wù)場(chǎng)景。

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>27.1-jre</version>
</dependency>

 3. ExpiryMap

這是網(wǎng)上某位大佬自己封裝的map,繼承至HashMap,重寫了所有對(duì)外的方法,對(duì)每個(gè)key值都設(shè)置了有效期。

我在其基礎(chǔ)上增加了使用單例模式獲取map。

import java.util.*;

/**
 * @Title: ExpiryMap 可以設(shè)置過(guò)期時(shí)間的Map
 * @description ExpiryMap繼承至HashMap 重寫了所有對(duì)外的方法,對(duì)每個(gè)key值都設(shè)置了有效期
 * @Author: xx
 * @Version: 1.0
 */
public class ExpiryMap<K, V> extends HashMap<K, V> {

  private static final long serialVersionUID = 1L;

  /**
   * default expiry time 2s
   */
  private long EXPIRY = 1000 * 2;

  private HashMap<K, Long> expiryMap = new HashMap<>();

  /** 緩存實(shí)例對(duì)象 */
  private volatile static ExpiryMap<String, String> SameUrlMap;

  /**
   * 采用單例模式獲取實(shí)例
   * @return
   */
  public static ExpiryMap getInstance() {
    //第一次判空,提高效率
    if (null == SameUrlMap) {
      //保證線程安全
      synchronized (ExpiryMap.class) {
        //第二次判空,保證單例對(duì)象的唯一性,防止第一次有多個(gè)線程進(jìn)入第一個(gè)if判斷
        if (null == SameUrlMap) {
          SameUrlMap = new ExpiryMap<>();
        }
      }
    }
    return SameUrlMap;
  }

  public ExpiryMap(){
    super();
  }

  public ExpiryMap(long defaultExpiryTime){
    this(1 << 4, defaultExpiryTime);
  }

  public ExpiryMap(int initialCapacity, long defaultExpiryTime){
    super(initialCapacity);
    this.EXPIRY = defaultExpiryTime;
  }

  @Override
  public V put(K key, V value) {
    expiryMap.put(key, System.currentTimeMillis() + EXPIRY);
    return super.put(key, value);
  }

  @Override
  public boolean containsKey(Object key) {
    return !checkExpiry(key, true) && super.containsKey(key);
  }
  /**
   * @param key
   * @param value
   * @param expiryTime 鍵值對(duì)有效期 毫秒
   * @return
   */
  public V put(K key, V value, long expiryTime) {
    expiryMap.put(key, System.currentTimeMillis() + expiryTime);
    return super.put(key, value);
  }

  @Override
  public int size() {
    return entrySet().size();
  }

  @Override
  public boolean isEmpty() {
    return entrySet().size() == 0;
  }

  @Override
  public boolean containsValue(Object value) {
    if (value == null) {
      return Boolean.FALSE;
    }
    Set<Entry<K, V>> set = super.entrySet();
    Iterator<Entry<K, V>> iterator = set.iterator();
    while (iterator.hasNext()) {
      java.util.Map.Entry<K, V> entry = iterator.next();
      if(value.equals(entry.getValue())){
        if(checkExpiry(entry.getKey(), false)) {
          iterator.remove();
          return Boolean.FALSE;
        }else {
          return Boolean.TRUE;
        }
      }
    }
    return Boolean.FALSE;
  }

  @Override
  public Collection<V> values() {

    Collection<V> values = super.values();

    if(values == null || values.size() < 1) {
      return values;
    }

    Iterator<V> iterator = values.iterator();

    while (iterator.hasNext()) {
      V next = iterator.next();
      if(!containsValue(next)) {
        iterator.remove();
      }
    }
    return values;
  }

  @Override
  public V get(Object key) {
    if (key == null) {
      return null;
    }
    if(checkExpiry(key, true)) {
      return null;
    }
    return super.get(key);
  }
  /**
   *
   * @Description: 是否過(guò)期
   * @param key
   * @return null:不存在或key為null -1:過(guò)期 存在且沒(méi)過(guò)期返回value 因?yàn)檫^(guò)期的不是實(shí)時(shí)刪除,所以稍微有點(diǎn)作用
   */
  public Object isInvalid(Object key) {
    if (key == null) {
      return null;
    }
    if(!expiryMap.containsKey(key)){
      return null;
    }
    long expiryTime = expiryMap.get(key);

    boolean flag = System.currentTimeMillis() > expiryTime;

    if(flag){
      super.remove(key);
      expiryMap.remove(key);
      return -1;
    }
    return super.get(key);
  }

  @Override
  public void putAll(Map<? extends K, ? extends V> m) {
    for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
      expiryMap.put(e.getKey(), System.currentTimeMillis() + EXPIRY);
    }
    super.putAll(m);
  }

  @Override
  public Set<Map.Entry<K,V>> entrySet() {
    Set<java.util.Map.Entry<K, V>> set = super.entrySet();
    Iterator<java.util.Map.Entry<K, V>> iterator = set.iterator();
    while (iterator.hasNext()) {
      java.util.Map.Entry<K, V> entry = iterator.next();
      if(checkExpiry(entry.getKey(), false)) {
        iterator.remove();
      }
    }

    return set;
  }
  /**
   *
   * @Description: 是否過(guò)期
   * @param expiryTime true 過(guò)期
   * @param isRemoveSuper true super刪除
   * @return
   */
  private boolean checkExpiry(Object key, boolean isRemoveSuper){

    if(!expiryMap.containsKey(key)){
      return Boolean.FALSE;
    }
    long expiryTime = expiryMap.get(key);

    boolean flag = System.currentTimeMillis() > expiryTime;

    if(flag){
      if(isRemoveSuper) {
        super.remove(key);
      }
      expiryMap.remove(key);
    }
    return flag;
  }

  public static void main(String[] args) throws InterruptedException {
    ExpiryMap<String, String> map = new ExpiryMap<>();
    map.put("test", "xxx");
    map.put("test2", "ankang", 5000);
    System.out.println("test==" + map.get("test"));
    Thread.sleep(3000);
    System.out.println("test==" + map.get("test"));
    System.out.println("test2==" + map.get("test2"));
    Thread.sleep(3000);
    System.out.println("test2==" + map.get("test2"));
  }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解SpringBoot封裝使用JDBC

    詳解SpringBoot封裝使用JDBC

    這篇文章主要介紹了SpringBoot封裝JDBC使用教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • springboot實(shí)現(xiàn)郵箱發(fā)送(激活碼)功能的示例代碼

    springboot實(shí)現(xiàn)郵箱發(fā)送(激活碼)功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用springboot實(shí)現(xiàn)郵箱發(fā)送(激活碼)功能,文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • springboot application.properties 文件注入數(shù)組方式

    springboot application.properties 文件注入數(shù)組方式

    這篇文章主要介紹了springboot application.properties 文件注入數(shù)組方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • RequestContextHolder.getRequestAttributes()空指針問(wèn)題及解決

    RequestContextHolder.getRequestAttributes()空指針問(wèn)題及解決

    這篇文章主要介紹了RequestContextHolder.getRequestAttributes()空指針問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java MyBatis攔截器Inteceptor詳細(xì)介紹

    java MyBatis攔截器Inteceptor詳細(xì)介紹

    這篇文章主要介紹了java MyBatis攔截器Inteceptor詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • VSCode+Gradle搭建Java開發(fā)環(huán)境實(shí)現(xiàn)

    VSCode+Gradle搭建Java開發(fā)環(huán)境實(shí)現(xiàn)

    這篇文章主要介紹了VSCode+Gradle搭建Java開發(fā)環(huán)境實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • JFINAL+Ajax傳參 array 數(shù)組方法 獲取request中數(shù)組操作

    JFINAL+Ajax傳參 array 數(shù)組方法 獲取request中數(shù)組操作

    這篇文章主要介紹了JFINAL+Ajax傳參 array 數(shù)組方法 獲取request中數(shù)組操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • IDEA項(xiàng)目的依賴(pom.xml文件)導(dǎo)入問(wèn)題及解決

    IDEA項(xiàng)目的依賴(pom.xml文件)導(dǎo)入問(wèn)題及解決

    這篇文章主要介紹了IDEA項(xiàng)目的依賴(pom.xml文件)導(dǎo)入問(wèn)題及解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Spring?Boot實(shí)現(xiàn)分布式系統(tǒng)中的服務(wù)發(fā)現(xiàn)和注冊(cè)(最新推薦)

    Spring?Boot實(shí)現(xiàn)分布式系統(tǒng)中的服務(wù)發(fā)現(xiàn)和注冊(cè)(最新推薦)

    在本文中,我們深入探討了Spring?Boot如何實(shí)現(xiàn)分布式系統(tǒng)中的服務(wù)發(fā)現(xiàn)和注冊(cè),我們使用Eureka作為服務(wù)注冊(cè)中心,Ribbon作為負(fù)載均衡器,Hystrix作為熔斷器,成功地實(shí)現(xiàn)了服務(wù)發(fā)現(xiàn)、服務(wù)注冊(cè)、負(fù)載均衡和服務(wù)熔斷等功能,需要的朋友參考下吧
    2023-06-06
  • spring中bean id相同引發(fā)故障的分析與解決

    spring中bean id相同引發(fā)故障的分析與解決

    最近在工作中遇到了關(guān)于bean id相同引發(fā)故障的問(wèn)題,通過(guò)查找相關(guān)資料終于解決了,下面這篇文章主要給大家介紹了因?yàn)閟pring中bean id相同引發(fā)故障的分析與解決方法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-09-09

最新評(píng)論

镇沅| 淳安县| 隆林| 恩施市| 化州市| 平南县| 巩义市| 蒙城县| 固镇县| 吕梁市| 商南县| 四会市| 顺平县| 会理县| 绥中县| 兴义市| 嘉义县| 阳西县| 盐山县| 古田县| 滦南县| 蒙阴县| 腾冲县| 五常市| 吉安县| 滦南县| 扎鲁特旗| 嘉黎县| 丰城市| 什邡市| 如皋市| 合肥市| 咸宁市| 冷水江市| 城步| 图们市| 嵩明县| 汾阳市| 汪清县| 临西县| 邯郸市|