黄视频网站在线免费观看-黄视频网站在线看-黄视频网站在线观看-黄视频网站免费看-黄视频网站免费观看-黄视频网站免费

千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機構(gòu)

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領(lǐng)取全套視頻
千鋒教育

關(guān)注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術(shù)干貨  > 千鋒Java培訓分享如何設計一個本地緩存

千鋒Java培訓分享如何設計一個本地緩存

來源:千鋒教育
發(fā)布人:劉老師
時間: 2020-07-08 18:05:00 1594202700

前言

最近在看Mybatis的源碼,剛好看到緩存這一塊,Mybatis提供了一級緩存和二級緩存;一級緩存相對來說比較簡單,功能比較齊全的是二級緩存,基本上滿足了一個緩存該有的功能;當然如果拿來和專門的緩存框架如ehcache來對比可能稍有差距;本文千鋒Java培訓講師帶大家來整理一下實現(xiàn)一個本地緩存都應該需要考慮哪些東西。

考慮點

考慮點主要在數(shù)據(jù)用何種方式存儲,能存儲多少數(shù)據(jù),多余的數(shù)據(jù)如何處理等幾個點,下面我們來詳細的介紹每個考慮點,以及該如何去實現(xiàn);

1.數(shù)據(jù)結(jié)構(gòu)

首要考慮的就是數(shù)據(jù)該如何存儲,用什么數(shù)據(jù)結(jié)構(gòu)存儲,最簡單的就直接用Map來存儲數(shù)據(jù);或者復雜的如redis一樣提供了多種數(shù)據(jù)類型哈希,列表,集合,有序集合等,底層使用了雙端鏈表,壓縮列表,集合,跳躍表等數(shù)據(jù)結(jié)構(gòu);

2.對象上限

因為是本地緩存,內(nèi)存有上限,所以一般都會指定緩存對象的數(shù)量比如1024,當達到某個上限后需要有某種策略去刪除多余的數(shù)據(jù);

3.清除策略

上面說到當達到對象上限之后需要有清除策略,常見的比如有LRU(最近最少使用)、FIFO(先進先出)、LFU(最近最不常用)、SOFT(軟引用)、WEAK(弱引用)等策略;

4.過期時間

除了使用清除策略,一般本地緩存也會有一個過期時間設置,比如redis可以給每個key設置一個過期時間,這樣當達到過期時間之后直接刪除,采用清除策略+過期時間雙重保證;

5.線程安全

像redis是直接使用單線程處理,所以就不存在線程安全問題;而我們現(xiàn)在提供的本地緩存往往是可以多個線程同時訪問的,所以線程安全是不容忽視的問題;并且線程安全問題是不應該拋給使用者去保證;

6.簡明的接口

提供一個傻瓜式的對外接口是很有必要的,對使用者來說使用此緩存不是一種負擔而是一種享受;提供常用的get,put,remove,clear,getSize方法即可;

7.是否持久化

這個其實不是必須的,是否需要將緩存數(shù)據(jù)持久化看需求;本地緩存如ehcache是支持持久化的,而guava是沒有持久化功能的;分布式緩存如redis是有持久化功能的,memcached是沒有持久化功能的;

8.阻塞機制

在看Mybatis源碼的時候,二級緩存提供了一個blocking標識,表示當在緩存中找不到元素時,它設置對緩存鍵的鎖定;這樣其他線程將等待此元素被填充,而不是命中數(shù)據(jù)庫;其實我們使用緩存的目的就是因為被緩存的數(shù)據(jù)生成比較費時,比如調(diào)用對外的接口,查詢數(shù)據(jù)庫,計算量很大的結(jié)果等等;這時候如果多個線程同時調(diào)用get方法獲取的結(jié)果都為null,每個線程都去執(zhí)行一遍費時的計算,其實也是對資源的浪費;比較好的辦法是只有一個線程去執(zhí)行,其他線程等待,計算一次就夠了;但是此功能基本上都交給使用者來處理,很少有本地緩存有這種功能;

如何實現(xiàn)

以上大致介紹了實現(xiàn)一個本地緩存我們都有哪些需要考慮的地方,當然可能還有其他沒有考慮到的點;下面繼續(xù)看看關(guān)于每個點都應該如何去實現(xiàn),重點介紹一下思路;

1.數(shù)據(jù)結(jié)構(gòu)

本地緩存最常見的是直接使用Map來存儲,比如guava使用ConcurrentHashMap,ehcache也是用了ConcurrentHashMap,Mybatis二級緩存使用HashMap來存儲:

Map<Object, Object> cache = new ConcurrentHashMap<Object, Object>()

Mybatis使用HashMap本身是非線程安全的,所以可以看到起內(nèi)部使用了一個SynchronizedCache用來包裝,保證線程的安全性;

當然除了使用Map來存儲,可能還使用其他數(shù)據(jù)結(jié)構(gòu)來存儲,比如redis使用了雙端鏈表,壓縮列表,整數(shù)集合,跳躍表和字典;當然這主要是因為redis對外提供的接口很豐富除了哈希還有列表,集合,有序集合等功能;

2.對象上限

本地緩存常見的一個屬性,一般緩存都會有一個默認值比如1024,在用戶沒有指定的情況下默認指定;當緩存的數(shù)據(jù)達到指定最大值時,需要有相關(guān)策略從緩存中清除多余的數(shù)據(jù)這就涉及到下面要介紹的清除策略;

3.清除策略

配合對象上限之后使用,場景的清除策略如:LRU(最近最少使用)、FIFO(先進先出)、LFU(最近最不常用)、SOFT(軟引用)、WEAK(弱引用);

LRU:Least Recently Used的縮寫最近最少使用,移除最長時間不被使用的對象;常見的使用LinkedHashMap來實現(xiàn),也是很多本地緩存默認使用的策略;

FIFO:先進先出,按對象進入緩存的順序來移除它們;常見使用隊列Queue來實現(xiàn);

LFU:Least Frequently Used的縮寫大概也是最近最少使用的意思,和LRU有點像;區(qū)別點在LRU的淘汰規(guī)則是基于訪問時間,而LFU是基于訪問次數(shù)的;可以通過HashMap并且記錄訪問次數(shù)來實現(xiàn);

SOFT:軟引用基于垃圾回收器狀態(tài)和軟引用規(guī)則移除對象;常見使用SoftReference來實現(xiàn);

WEAK:弱引用更積極地基于垃圾收集器狀態(tài)和弱引用規(guī)則移除對象;常見使用WeakReference來實現(xiàn);

4.過期時間

設置過期時間,讓緩存數(shù)據(jù)在指定時間過后自動刪除;常見的過期數(shù)據(jù)刪除策略有兩種方式:被動刪除和主動刪除;

被動刪除:每次進行g(shù)et/put操作的時候都會檢查一下當前key是否已經(jīng)過期,如果過期則刪除,類似如下代碼:

if (System.currentTimeMillis() - lastClear > clearInterval) {

clear();

}

主動刪除:專門有一個job在后臺定期去檢查數(shù)據(jù)是否過期,如果過期則刪除,這其實可以有效的處理冷數(shù)據(jù);

5.線程安全

盡量用線程安全的類去存儲數(shù)據(jù),比如使用ConcurrentHashMap代替HashMap;或者提供相應的同步處理類,比如Mybatis提供了SynchronizedCache:

public synchronized void putObject(Object key, Object object) {

...省略...

}

@Override

public synchronized Object getObject(Object key) {

...省略...

}

6.簡明的接口

提供常用的get,put,remove,clear,getSize方法即可,比如Mybatis的Cache接口:

public interface Cache {

String getId();

void putObject(Object key, Object value);

Object getObject(Object key);

Object removeObject(Object key);

void clear();

int getSize();

ReadWriteLock getReadWriteLock();

}

再來看看guava提供的Cache接口,相對來說也是比較簡潔的:

public interface Cache<K, V> {

V getIfPresent(@CompatibleWith("K") Object key);

V get(K key, Callable<? extends V> loader) throws ExecutionException;

ImmutableMap<K, V> getAllPresent(Iterable<?> keys);

void put(K key, V value);

void putAll(Map<? extends K, ? extends V> m);

void invalidate(@CompatibleWith("K") Object key);

void invalidateAll(Iterable<?> keys);

void invalidateAll();

long size();

CacheStats stats();

ConcurrentMap<K, V> asMap();

void cleanUp();

}

7.是否持久化

持久化的好處是重啟之后可以再次加載文件中的數(shù)據(jù),這樣就起到類似熱加載的功效;比如ehcache提供了是否持久化磁盤緩存的功能,將緩存數(shù)據(jù)存放在一個.data文件中;

diskPersistent="false" //是否持久化磁盤緩存

redis更是將持久化功能發(fā)揮到極致,慢慢的有點像數(shù)據(jù)庫了;提供了AOF和RDB兩種持久化方式;當然很多情況下可以配合使用兩種方式;

8.阻塞機制

除了在Mybatis中看到了BlockingCache來實現(xiàn)此功能,之前在看<<java并發(fā)編程實戰(zhàn)>>的時候其中有實現(xiàn)一個很完美的緩存,大致代碼如下:

public class Memoizerl<A, V> implements Computable<A, V> {

private final Map<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>();

private final Computable<A, V> c;

public Memoizerl(Computable<A, V> c) {

this.c = c;

}

@Override

public V compute(A arg) throws InterruptedException, ExecutionException {

while (true) {

Future<V> f = cache.get(arg);

if (f == null) {

Callable<V> eval = new Callable<V>() {

@Override

public V call() throws Exception {

return c.compute(arg);

}

};

FutureTask<V> ft = new FutureTask<V>(eval);

f = cache.putIfAbsent(arg, ft);

if (f == null) {

f = ft;

ft.run();

}

try {

return f.get();

} catch (CancellationException e) {

cache.remove(arg, f);

}

}

}

}

}

compute是一個計算很費時的方法,所以這里把計算的結(jié)果緩存起來,但是有個問題就是如果兩個線程同時進入此方法中怎么保證只計算一次,這里最核心的地方在于使用了ConcurrentHashMap的putIfAbsent方法,同時只會寫入一個FutureTask;

總結(jié):要設計一個本地緩存都需要考慮哪些點:數(shù)據(jù)結(jié)構(gòu),對象上限,清除策略,過期時間,線程安全,阻塞機制,實用的接口,是否持久化;當然肯定有其他考慮點,歡迎補充。

tags:
聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
10年以上業(yè)內(nèi)強師集結(jié),手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內(nèi)將與您1V1溝通
免費領(lǐng)取
今日已有369人領(lǐng)取成功
劉同學 138****2860 剛剛成功領(lǐng)取
王同學 131****2015 剛剛成功領(lǐng)取
張同學 133****4652 剛剛成功領(lǐng)取
李同學 135****8607 剛剛成功領(lǐng)取
楊同學 132****5667 剛剛成功領(lǐng)取
岳同學 134****6652 剛剛成功領(lǐng)取
梁同學 157****2950 剛剛成功領(lǐng)取
劉同學 189****1015 剛剛成功領(lǐng)取
張同學 155****4678 剛剛成功領(lǐng)取
鄒同學 139****2907 剛剛成功領(lǐng)取
董同學 138****2867 剛剛成功領(lǐng)取
周同學 136****3602 剛剛成功領(lǐng)取
相關(guān)推薦HOT
亚欧成人毛片一区二区三区四区| 国产麻豆精品| 精品视频在线观看一区二区| 久久精品欧美一区二区| 日韩avdvd| 青青久久精品| 久久成人亚洲| 日韩欧美一及在线播放| 亚洲天堂一区二区三区四区| 日韩一级黄色| 亚洲www美色| 欧美另类videosbestsex视频| 日韩在线观看视频网站| 国产麻豆精品hdvideoss| 久久国产一久久高清| 午夜在线观看视频免费 成人| 麻豆系列国产剧在线观看| 九九免费高清在线观看视频| 黄视频网站在线免费观看| 精品在线视频播放| 国产伦精品一区二区三区无广告| 久久久成人影院| 亚洲天堂在线播放| 日日夜人人澡人人澡人人看免| 日韩专区在线播放| 免费国产在线观看不卡| 成人影院久久久久久影院| 精品视频一区二区三区免费| 欧美a免费| 国产成人欧美一区二区三区的| 久久精品人人做人人爽97| 99久久网站| 色综合久久天天综合| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 成人免费观看的视频黄页| 日韩av成人| 日韩一级黄色| 天天做人人爱夜夜爽2020| 精品在线视频播放| 精品国产一区二区三区久 | 国产精品自拍在线观看| 日本在线www| 国产麻豆精品hdvideoss| 国产a视频| 国产极品精频在线观看| 欧美另类videosbestsex视频| 色综合久久手机在线| 一本高清在线| 国产福利免费观看| 免费国产一级特黄aa大片在线| 天天做人人爱夜夜爽2020| 91麻豆高清国产在线播放| 亚洲精品中文字幕久久久久久| 一级女性大黄生活片免费| 国产美女在线观看| 欧美电影免费| 国产原创视频在线| 免费国产在线观看| 成人a级高清视频在线观看| 国产91丝袜在线播放0| 午夜久久网| 青草国产在线| 青青久热| 韩国毛片基地| 免费国产一级特黄aa大片在线| 国产原创视频在线| 久久国产一久久高清| 欧美另类videosbestsex高清| 欧美激情影院| 日本伦理片网站| 精品视频在线看| 美女免费毛片| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 日韩在线观看视频黄| 国产视频一区二区在线播放| 午夜精品国产自在现线拍| 国产麻豆精品视频| 国产麻豆精品高清在线播放| 国产成人精品影视| 青青久在线视频| 日本特黄特黄aaaaa大片| 韩国三级视频网站| 九九精品久久| 欧美a级片视频| 深夜做爰性大片中文| 青青青草影院| 九九免费高清在线观看视频| 韩国毛片 免费| 国产一级强片在线观看| 国产伦精品一区二区三区在线观看| 台湾毛片| 国产成人啪精品| 久久国产精品自线拍免费| 高清一级片| 国产激情视频在线观看| 欧美激情一区二区三区视频高清| 欧美a级片视频| 国产伦精品一区二区三区无广告| 91麻豆精品国产自产在线| 香蕉视频一级| 日本免费看视频| 国产综合91天堂亚洲国产| 国产91精品系列在线观看| 亚洲 欧美 91| 欧美一级视| 999久久久免费精品国产牛牛| 韩国三级视频网站| 久久福利影视| 欧美a免费| 一级女性全黄生活片免费| 国产伦久视频免费观看 视频 | 国产亚洲免费观看| 国产91精品系列在线观看| 中文字幕一区二区三区 精品| 国产网站免费| 日日日夜夜操| 九九精品在线| 高清一级毛片一本到免费观看| 国产一级强片在线观看| 久久精品店| 青青久久精品| 久久成人亚洲| 四虎精品在线观看| 九九精品久久| 可以在线看黄的网站| 天天做日日干| 四虎论坛| 国产原创视频在线| 亚洲天堂免费观看| 九九精品在线播放| 久久国产影院| 国产极品精频在线观看| 欧美大片aaaa一级毛片| 欧美激情一区二区三区在线播放| 久草免费在线色站| 欧美激情一区二区三区视频高清| 欧美日本二区| 美女免费毛片| 香蕉视频三级| 国产麻豆精品免费密入口| 沈樵在线观看福利| 高清一级片| 日韩免费在线视频| 久久久成人网| 久久福利影视| 色综合久久天天综合绕观看| 四虎影视久久久| 99热热久久| 久久国产精品永久免费网站| 高清一级片| 日日夜人人澡人人澡人人看免| 欧美激情在线精品video| 日韩专区一区| 日韩专区一区| 日韩专区第一页| 精品久久久久久免费影院| 日本伦理片网站| 麻豆系列 在线视频| 91麻豆国产福利精品| 青青青草视频在线观看| 日韩中文字幕一区| 欧美激情一区二区三区在线| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 91麻豆精品国产综合久久久| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 日韩在线观看免费| 日本免费区| 九九久久国产精品大片| 精品视频一区二区三区| 亚洲天堂免费观看| 午夜激情视频在线观看| 一级片片| 成人高清视频免费观看| 久久福利影视| 亚洲 男人 天堂| 99色视频在线观看| 天天色成人| 午夜精品国产自在现线拍| 可以免费在线看黄的网站| 精品久久久久久中文字幕一区 | 日韩专区一区| 亚洲精品中文字幕久久久久久| 国产麻豆精品视频| 国产麻豆精品视频| 香蕉视频久久| 韩国三级视频网站| 四虎影视库国产精品一区| 国产视频久久久久| 久久国产精品永久免费网站| 黄色福利| 一级女性全黄生活片免费| 国产网站免费| 日韩在线观看视频网站| 成人a级高清视频在线观看| 九九九在线视频| 欧美1区| 一级女性全黄生活片免费| 久久国产精品自线拍免费| 午夜欧美成人久久久久久| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 |