Java設(shè)計實現(xiàn)一個針對各種類型的緩存
1. 設(shè)計頂層接口
// 定義為一個泛型接口,提供給抽象類使用
public interface CacheManager<T> {
// 獲取所有的緩存item
List<T> getAll();
// 根據(jù)條件獲取某些緩存item
List<T> get(Predicate<T> predicate);
// 設(shè)置緩存
boolean set(T t);
// 設(shè)置緩存list
boolean set(List<T> tList);
}
有接口必定有實現(xiàn)類或者抽象類,實現(xiàn)接口。
那為了更好地控制子類的行為,可以做一個抽象類,控制子類行為。
分析:
- 抽象類作為緩存管理的話,那么就需要提供安全訪問數(shù)據(jù)
- 需要考慮線程安全問題。
- 花絮: 不僅要滿足上述需求,而且讓代碼盡量簡潔。
2. 設(shè)計抽象類 – AbstractCacheManager
屬性設(shè)計:
- 需要一個緩存
- 需要一個線程安全機制方案
行為設(shè)計:
自己的行為:
- 利用線程安全機制控制緩存的讀寫。
- 權(quán)限:僅自己可訪問
后代的行為:
- 訪問一些簡單api方法即可實現(xiàn)安全訪問緩存
- 權(quán)限:公共訪問
設(shè)計模式:
包裹思想,將后代行為方法中,包裹一層安全訪問的行為。
Java Code:
// properties design:
protected ConcurrentMap<String, T> cache;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
// subclass to implements these abstract methods.
protected abstract List<T> getAllByCache();
protected abstract void setByCache(T t);
protected abstract void setByCache(List<T> tList);
protected abstract List<T> getByCache(Predicate<T> predicate);
// next content needs to consider safety of multithreads. following methods do implements.
// entry to use
@Override
public final List<T> getAll() {
return this.readLockThenGet(() -> this.getAllByCache());
}
@Override
public final List<T> get(Predicate<T> predicate) {
return this.readLockThenGet(pre -> getByCache(pre), predicate);
}
@Override
public final boolean set(T t) {
return this.writeLockThenSet((Consumer<T>) obj -> set(obj), t);
}
@Override
public final boolean set(List<T> tList) {
return this.writeLockThenSet((Consumer<List<T>>) list -> set(list), tList);
}
// current abstract class access cache object.
private boolean writeLockThenSet(Consumer consumer, Object object){
boolean wLock = false;
try {
if (!(wLock = lock.writeLock().tryLock(100, TimeUnit.MICROSECONDS))) {
return false;
}
consumer.accept(object);
return true;
} catch (Exception e) {
return false;
} finally {
if(wLock) {
lock.writeLock().unlock();
}
}
}
private List<T> readLockThenGet(Supplier<List<T>> supplier){
boolean rLock = false;
try{
if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){
return null;
}
return supplier.get();
}catch (Exception e){
return null;
}finally {
if(rLock) {
lock.readLock().unlock();
}
}
}
private List<T> readLockThenGet(Function<Predicate<T>, List<T>> function, Predicate<T> predicate){
boolean rLock = false;
try{
if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){
return null;
}
return function.apply(predicate);
}catch (Exception e){
return null;
}finally {
if(rLock) {
lock.readLock().unlock();
}
}
}
3. 具體子類
3.1 – AlertRuleItemExpCacheManager
@Component("alertRuleItemExpCacheManager")
public class AlertRuleItemExpCacheManager<T extends AlertRuleItemExpCache> extends AbstractCacheManager<AlertRuleItemExpCache> {
@Resource
private AlertRuleItemExpDao alertRuleItemExpDao;
@Override
protected List<AlertRuleItemExpCache> getAllByCache() {
if (null == cache) {
List<AlertRuleItemExp> alertRuleItemSrcList =
alertRuleItemExpDao.selectList(Wrappers.<AlertRuleItemExp>lambdaQuery().eq(AlertRuleItemExp::getDeleted, 0));
cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache())
.collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));
}
return cache.values().stream()
.sorted(Comparator.comparing(AlertRuleItemExpCache::getId))
.collect(Collectors.toList());
}
@Override
protected void setByCache(AlertRuleItemExpCache alertRuleItemExpCache) {
cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache);
}
@Override
protected void setByCache(List<AlertRuleItemExpCache> alertRuleItemExpCacheList) {
alertRuleItemExpCacheList.parallelStream().forEach(alertRuleItemExpCache ->
cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache));
}
@Override
protected List<AlertRuleItemExpCache> getByCache(Predicate<AlertRuleItemExpCache> predicate) {
return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());
}
}
3.2 – AlertRuleItemSrcCacheManager
@Component("alertRuleItemSrcCacheManager")
public class AlertRuleItemSrcCacheManager<T extends AlertRuleItemSrcCache> extends AbstractCacheManager<AlertRuleItemSrcCache> {
@Resource
private AlertRuleItemSrcDao alertRuleItemSrcDao;
@Override
protected List<AlertRuleItemSrcCache> getAllByCache() {
if (null == cache) {
List<AlertRuleItemSrc> alertRuleItemSrcList =
alertRuleItemSrcDao.selectList(Wrappers.<AlertRuleItemSrc>lambdaQuery().eq(AlertRuleItemSrc::getDeleted, 0));
cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache())
.collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));
}
return cache.values().stream()
.sorted(Comparator.comparing(AlertRuleItemSrcCache::getId))
.collect(Collectors.toList());
}
@Override
protected void setByCache(AlertRuleItemSrcCache alertRuleItemSrcCache) {
cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache);
}
@Override
protected void setByCache(List<AlertRuleItemSrcCache> alertRuleItemSrcCacheList) {
alertRuleItemSrcCacheList.parallelStream().forEach(alertRuleItemSrcCache ->
cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache));
}
@Override
protected List<AlertRuleItemSrcCache> getByCache(Predicate<AlertRuleItemSrcCache> predicate) {
return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());
}
}
4. 類圖關(guān)系

以上就是Java設(shè)計實現(xiàn)一個針對各種類型的緩存的詳細(xì)內(nèi)容,更多關(guān)于Java緩存的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
通過Mybatis實現(xiàn)單表內(nèi)一對多的數(shù)據(jù)展示示例代碼
最近做項目遇到這樣的需求要求將表中的數(shù)據(jù),按照一級二級分類返回給前端json數(shù)據(jù),下面通過本文給大家分享通過Mybatis實現(xiàn)單表內(nèi)一對多的數(shù)據(jù)展示示例代碼,感興趣的朋友參考下吧2017-08-08
java?poi之XWPFDocument如何讀取word內(nèi)容并創(chuàng)建新的word
這篇文章主要介紹了java?poi之XWPFDocument如何讀取word內(nèi)容并創(chuàng)建新的word問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04
如何使用Spring Cloud Feign日志查看請求響應(yīng)
這篇文章主要介紹了如何使用Spring Cloud Feign日志查看請求響應(yīng),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-02-02
java基本教程之java線程等待與java喚醒線程 java多線程教程
這篇文章主要介紹了對線程等待/喚醒方法,文中使用了多個示例,大家參考使用吧2014-01-01
IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實現(xiàn)
這篇文章主要介紹了IntelliJ IDEA 統(tǒng)一設(shè)置編碼為utf-8編碼的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2020-06-06

