您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關怎么在Java中設置緩存Map過期時間,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
1. ExpiringMap
功能簡介 :
1.可設置Map中的Entry在一段時間后自動過期。
2.可設置Map最大容納值,當到達Maximum size后,再次插入值會導致Map中的第一個值過期。
3.可添加監聽事件,在監聽到Entry過期時調度監聽函數。
4.可以設置懶加載,在調用get()方法時創建對象。
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開源出來的一個線程安全的本地緩存解決方案。
特點:提供緩存回收機制,監控緩存加載/命中情況,靈活強大的功能,簡單易上手的api
但是該cache不會在特定時間準時回收鍵值,所以不適用于我當前的業務場景。
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.1-jre</version> </dependency>
3. ExpiryMap
這是網上某位大佬自己封裝的map,繼承至HashMap,重寫了所有對外的方法,對每個key值都設置了有效期。
我在其基礎上增加了使用單例模式獲取map。
import java.util.*; /** * @Title: ExpiryMap 可以設置過期時間的Map * @description ExpiryMap繼承至HashMap 重寫了所有對外的方法,對每個key值都設置了有效期 * @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<>(); /** 緩存實例對象 */ private volatile static ExpiryMap<String, String> SameUrlMap; /** * 采用單例模式獲取實例 * @return */ public static ExpiryMap getInstance() { //第一次判空,提高效率 if (null == SameUrlMap) { //保證線程安全 synchronized (ExpiryMap.class) { //第二次判空,保證單例對象的唯一性,防止第一次有多個線程進入第一個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 鍵值對有效期 毫秒 * @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: 是否過期 * @param key * @return null:不存在或key為null -1:過期 存在且沒過期返回value 因為過期的不是實時刪除,所以稍微有點作用 */ 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: 是否過期 * @param expiryTime true 過期 * @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")); } }
Java中的集合主要分為四類:1、List列表:有序的,可重復的;2、Queue隊列:有序,可重復的;3、Set集合:不可重復;4、Map映射:無序,鍵唯一,值不唯一。
看完上述內容,你們對怎么在Java中設置緩存Map過期時間有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。