平時項目中總會用到超時緩存,並且希望超時之後會觸發一些後續處理邏輯,比如心跳。一般做法就是把這些數據放到一個隊列中,然後線程定時遍歷檢查是否超時。於是想自己實現一個簡單的可以自動超時的緩存隊列。在查了一些資料後發現DelayQueue是非常合適而且非常簡便的,網絡上基於DelayQueue實現超時緩存隊列的文章也很多,本文實現的超時隊列原理類似,支持多次檢查並增加了一些超時回調方法。
DelayQueue介紹
功能演示
package ji.util;
import java.util.concurrent.TimeUnit;
/**
* Created by ji on 17-6-22.
*/
public class ExpireCacheTest {
public static void main(String[] args) throws InterruptedException {
//創建一個ExpireCache,
ExpireCache<String, String> expireCache = ExpireCache
// 四個參數分別是:首次超時時間,超時繼續檢查時間間隔,時間單位,超時後是否連續檢查
.setExpireTime(10, 2, TimeUnit.SECONDS, true)
//超時多少次從隊列中移除,第四個參數爲true纔有效,爲false時第一次超時就會被刪掉
.setCheckTimes(5)
//註冊一個超時回調,元素超時後會觸發handler方法
.build(new ExpireCallBack() {
@Override
public void handler(Object key, boolean isEnd) throws Exception {
System.out.println("元素:[" + key + "]超時,超時是否刪除:" + isEnd);
}
});
expireCache.put("key_a", "v_a");
expireCache.put("key_b", "v_b");
TimeUnit.SECONDS.sleep(2);
//expire會重新計算超時時間
expireCache.expire("key_a");
TimeUnit.SECONDS.sleep(2);
System.out.println(expireCache.get("key_a"));
//put可以更新已存在的值,並重新計算超時時間
expireCache.put("key_a", "v_a_new");
System.out.println(expireCache.get("key_a"));
Thread.sleep(100000000);
}
}
使用說明
ExpireCache<String, String> expireCache = ExpireCache
// 四個參數分別是:首次超時時間,超時繼續檢查時間間隔,時間單位,超時後是否連續檢查
.setExpireTime(10, 2, TimeUnit.SECONDS, true)
//超時多少次從隊列中移除,第四個參數爲true纔有效,爲false時第一次超時就會被刪掉
.setCheckTimes(5)
//註冊一個超時回調,元素超時後會觸發handler方法
.build(new ExpireCallBack() {
@Override
public void handler(Object key, boolean isEnd) throws Exception {
//回調方法邏輯
}
});
-
setExpireTime(long firstExpireTime, long subsequentExpireTime, TimeUnit unit, boolean continueCheckAfterExpire)
firstExpireTime : 超時時間
subsequentExpireTime : 下次檢查時間間隔,只有第四個參數爲true才生效unit:時間單位continueCheckAfterExpire: 超時後是否繼續檢查,false:失敗後直接從隊列中移除,true: 超時不移除,繼續檢查,和第二個參數配合
-
setCheckTimes(Integer times)
設置共檢查多少次,當設置連續檢查爲true時才生效。當檢查到達該次數後會從隊列中移除。 -
build(ExpireCallBack<K, V> callBack)
創建的時候可以傳一個回調函數,每次元素失效檢查的時候都會觸發該回調方法。 -
build()
當不需要回調的時候可以使用該方法創建。 -
put(K key, V value)
添加元素,有則更新,同時會重新計算超時時間。 -
V get(K key)
取元素 -
boolean containsKey(K key)
判斷是否存在該元素 -
boolean expire(K key)
更新超時時間,會重新計算超時。