日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

輕松了解java中Caffeine高性能緩存庫

瀏覽:24日期:2023-12-04 14:43:52
目錄輕松lCaffeine1、依賴2、寫入緩存 2.1、手動寫入2.2、同步加載2.3、異步加載3、緩存值的清理3.1、基于大小的清理3.2、基于時間的清理 3.3、基于引用的清理4、緩存刷新5、統(tǒng)計輕松lCaffeine1、依賴

我們需要將Caffeine依賴添加到我們的pom.xml中:

<dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.5.5</version></dependency>2、寫入緩存

讓我們關注Caffeine的三種緩存寫入策略:手動、同步加載和異步加載。

首先,讓我們編寫一個類,作為要存儲在緩存中的值的類型:

class DataObject { private final String data; private static int objectCounter = 0; // standard constructors/getterspublic static DataObject get(String data) {objectCounter++;return new DataObject(data); }} 2.1、手動寫入

在此策略中,我們手動將值寫入緩存并稍后讀取它們。

我們先初始化緩存:

Cache<String, DataObject> cache = Caffeine.newBuilder() .expireAfterWrite(1, TimeUnit.MINUTES) .maximumSize(100) .build();

現(xiàn)在,我們可以使用getIfPresent方法從緩存中獲取一些值。如果緩存中不存在該值,則此方法將返回null:

我們可以使用put方法手動寫入緩存:

cache.put(key, dataObject);dataObject = cache.getIfPresent(key);assertNotNull(dataObject);

我們還可以使用get方法獲取值,該方法接受一個函數(shù)和一個鍵作為參數(shù)。如果緩存中不存在該鍵,則此函數(shù)將用于提供兜底值,該值將在執(zhí)行后寫入緩存:

dataObject = cache .get(key, k -> DataObject.get('Data for A'));assertNotNull(dataObject);assertEquals('Data for A', dataObject.getData());

這個GET方法執(zhí)行是原子性的。這意味著即使多個線程同時請求該值,執(zhí)行只會進行一次。這就是為什么使用get比getIfPresent更好。

有時我們需要手動使一些緩存的值失效:

cache.invalidate(key);dataObject = cache.getIfPresent(key);assertNull(dataObject);2.2、同步加載

這種加載緩存的方法需要一個Function,用于初始化寫入值,類似于手動寫入策略的get方法,讓我們看看如何使用它。

首先,我們需要初始化我們的緩存:

現(xiàn)在我們可以使用get方法讀取值:

DataObject dataObject = cache.get(key);assertNotNull(dataObject);assertEquals('Data for ' + key, dataObject.getData());

我們還可以使用getAll方法獲取一組值:

Map<String, DataObject> dataObjectMap = cache.getAll(Arrays.asList('A', 'B', 'C'));assertEquals(3, dataObjectMap.size());

值從傳遞給build方法的底層后端初始化Function中讀取到,這樣就可以使用緩存作為訪問值的主要入口了。

2.3、異步加載

此策略的工作原理與前一個相同,但是會異步執(zhí)行操作并返回一個CompletableFuture來保存實際的值:

AsyncLoadingCache<String, DataObject> cache = Caffeine.newBuilder() .maximumSize(100) .expireAfterWrite(1, TimeUnit.MINUTES) .buildAsync(k -> DataObject.get('Data for ' + k));

我們可以以相同的方式使用get和getAll方法,考慮到它們的返回是CompletableFuture:

String key = 'A';cache.get(key).thenAccept(dataObject -> { assertNotNull(dataObject); assertEquals('Data for ' + key, dataObject.getData());});cache.getAll(Arrays.asList('A', 'B', 'C')) .thenAccept(dataObjectMap -> assertEquals(3, dataObjectMap.size()));

CompletableFuture具有很多有用的API,您可以在本文中閱讀更多相關信息。

3、緩存值的清理

Caffeine有三種緩存值的清理策略:基于大小、基于時間和基于引用。

3.1、基于大小的清理

這種類型的清理設計為在超出緩存配置的大小限制時發(fā)生清理。有兩種獲取大小的方法——計算緩存中的對象數(shù),或者獲取它們的權重。

讓我們看看如何計算緩存中的對象數(shù)。緩存初始化時,其大小為零:

LoadingCache<String, DataObject> cache = Caffeine.newBuilder() .maximumSize(1) .build(k -> DataObject.get('Data for ' + k));assertEquals(0, cache.estimatedSize());

當我們添加一個值時,大小明顯增加:

cache.get('A');assertEquals(1, cache.estimatedSize());

我們可以將第二個值添加到緩存中,這會導致刪除第一個值:

cache.get('B');cache.cleanUp();assertEquals(1, cache.estimatedSize());

值得一提的是,我們在獲取緩存大小之前調(diào)用了cleanUp方法。這是因為緩存清理是異步執(zhí)行的,該方法有助于等待清理完成。

我們還可以傳入一個weigher的Function來定義緩存大小的獲取:

LoadingCache<String, DataObject> cache = Caffeine.newBuilder() .maximumWeight(10) .weigher((k,v) -> 5) .build(k -> DataObject.get('Data for ' + k));assertEquals(0, cache.estimatedSize());cache.get('A');assertEquals(1, cache.estimatedSize());cache.get('B');assertEquals(2, cache.estimatedSize());

當權重超過 10 時,這些值將從緩存中刪除:

cache.get('C');cache.cleanUp();assertEquals(2, cache.estimatedSize());3.2、基于時間的清理

這種清理策略基于條目的過期時間,分為三種:

訪問后過期——自上次讀取或?qū)懭胍詠恚瑮l目在經(jīng)過某段時間后過期寫入后過期——自上次寫入以來,條目在經(jīng)過某段時間后過期自定義策略——由Expiry的實現(xiàn)來為每個條目單獨計算到期時間讓我們使用expireAfterAccess方法配置訪問后過期策略:

LoadingCache<String, DataObject> cache = Caffeine.newBuilder() .expireAfterAccess(5, TimeUnit.MINUTES) .build(k -> DataObject.get('Data for ' + k));

要配置寫入后過期策略,我們使用expireAfterWrite方法:

cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.SECONDS) .weakKeys() .weakValues() .build(k -> DataObject.get('Data for ' + k));

要初始化自定義策略,我們需要實現(xiàn)Expiry接口:

cache = Caffeine.newBuilder().expireAfter(new Expiry<String, DataObject>() { @Override public long expireAfterCreate( String key, DataObject value, long currentTime) {return value.getData().length() * 1000; } @Override public long expireAfterUpdate( String key, DataObject value, long currentTime, long currentDuration) {return currentDuration; } @Override public long expireAfterRead( String key, DataObject value, long currentTime, long currentDuration) {return currentDuration; }}).build(k -> DataObject.get('Data for ' + k)); 3.3、基于引用的清理

我們可以配置我們的緩存,允許緩存的鍵或值或二者一起的垃圾收集。為此,我們需要為鍵和值配置WeakReference的使用,并且我們可以配置SoftReference僅用于值的垃圾收集。

WeakReference的使用允許在沒有對對象的任何強引用時對對象進行垃圾回收。SoftReference允許基于JVM的全局LRU(最近最少使用)策略對對象進行垃圾回收。可以在此處找到有關Java中引用的更多詳細信息。

我們使用Caffeine.weakKeys()、Caffeine.weakValues()和Caffeine.softValues()來啟用每個選項:

LoadingCache<String, DataObject> cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.SECONDS) .weakKeys() .weakValues() .build(k -> DataObject.get('Data for ' + k));cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.SECONDS) .softValues() .build(k -> DataObject.get('Data for ' + k));4、緩存刷新

可以將緩存配置為在定義的時間段后自動刷新條目。讓我們看看如何使用refreshAfterWrite方法做到這一點:

Caffeine.newBuilder() .refreshAfterWrite(1, TimeUnit.MINUTES) .build(k -> DataObject.get('Data for ' + k));

在這里,我們應該明白expireAfter和refreshAfter的一個區(qū)別:當請求過期條目時,執(zhí)行會阻塞,直到build函數(shù)計算出新值。但是如果該條目符合刷新條件,則緩存將返回一個舊值并異步重新加載該值。

5、統(tǒng)計

Caffeine提供了一種記錄緩存使用統(tǒng)計信息的方法:

LoadingCache<String, DataObject> cache = Caffeine.newBuilder() .maximumSize(100) .recordStats() .build(k -> DataObject.get('Data for ' + k));cache.get('A');cache.get('A');assertEquals(1, cache.stats().hitCount());assertEquals(1, cache.stats().missCount());

到此這篇關于輕松了解java中Caffeine高性能緩存庫的文章就介紹到這了,更多相關java Caffeine緩存庫內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲调教视频在线观看| 石原莉奈在线亚洲三区| 亚洲综合小说| 亚洲经典在线| 亚洲高清久久| 亚洲一级二级| 蜜桃视频欧美| 免费精品国产| 欧美日韩激情在线一区二区三区| 欧美成人基地| 深夜视频一区二区| 久久久久国产| 国产在线不卡| 亚洲一区欧美激情| 美女黄网久久| 欧美午夜精品一区二区三区电影| 日韩大片在线| 色婷婷久久久| 好看的亚洲午夜视频在线| 亚洲女同中文字幕| 性色av一区二区怡红| 性一交一乱一区二区洋洋av| 蜜桃av一区二区| 亚洲精品乱码| 国产欧美日韩影院| 日韩精品久久理论片| 国产色99精品9i| 久久中文精品| 久久国产日韩| 鲁大师成人一区二区三区| 自由日本语亚洲人高潮| 亚洲一区欧美激情| 91综合久久爱com| 免费一区二区三区在线视频| 国产成人精品一区二区三区免费| 日韩专区精品| 国产精品日本| 91九色综合| 国产精品99一区二区三| 美女网站视频一区| 老牛影视一区二区三区| 一区二区三区国产在线| 欧美精品影院| 丰满少妇一区| 999国产精品视频| 99国产一区| 国产日产精品一区二区三区四区的观看方式| 国产免费播放一区二区| 日韩电影免费网址| 老色鬼久久亚洲一区二区| 国产精品久久久一区二区| 日韩精品第一区| 亚洲免费一区二区| 国产精品久久久久久模特| 成人日韩在线| 自拍自偷一区二区三区| 精品免费av在线| 亚洲开心激情| 高清久久精品| 一区二区国产精品| 国产精品一线天粉嫩av| 香蕉久久99| 久久精品 人人爱| 91tv亚洲精品香蕉国产一区| 日韩区一区二| 欧美日韩免费观看视频| 亚洲狼人精品一区二区三区| 久久久久久网| 亚洲综合福利| 黑森林国产精品av| 天海翼精品一区二区三区| 国产成人精品三级高清久久91| 99视频一区| 国产精品成人3p一区二区三区| 久久国产电影| 日韩国产在线观看一区| 久久精品青草| 嫩呦国产一区二区三区av| 另类亚洲自拍| 日韩精品免费一区二区三区| 国产精品1区| 亚洲精品伊人| 欧美天堂亚洲电影院在线观看| 成人黄色av| 欧美性www| 水野朝阳av一区二区三区| 精品国产第一福利网站| 日韩二区三区四区| 99热精品在线| 久久久精品网| 国产精品久久| 在线精品福利| 日韩高清中文字幕一区二区| 日本成人在线网站| 红桃视频国产一区| 国产福利资源一区| 日韩精品久久久久久久软件91| 婷婷综合福利| 夜夜精品视频| 精品国产黄a∨片高清在线| 国产精品嫩草99av在线| 国产精品18| 中文国产一区| 精品久久91| 久久wwww| 先锋影音久久久| 日韩欧美视频专区| 国产日韩欧美一区在线| 黄色亚洲在线| 色婷婷色综合| 亚洲永久精品唐人导航网址| 激情六月综合| 国产精品夜夜夜| 国产精品美女久久久浪潮软件| 精品国产网站| 日本aⅴ亚洲精品中文乱码| 黄色不卡一区| 国语精品一区| 日韩精品免费一区二区夜夜嗨| 中文字幕一区二区av| 国产白浆在线免费观看| 日韩精品国产精品| 欧美日韩国产在线观看网站| 精品深夜福利视频| 日本中文字幕视频一区| 国产日韩综合| 色婷婷狠狠五月综合天色拍| 欧美另类中文字幕| 首页欧美精品中文字幕| 久久黄色影院| 亚洲黄色免费看| 久久爱www成人| 青青国产91久久久久久| 免播放器亚洲| 久久久久国产精品一区三寸| 国产亚洲一区二区三区不卡| 蜜臀久久久99精品久久久久久| 久久婷婷丁香| 欧美精品成人| 国产日韩欧美一区在线| 亚洲精品自拍| 日韩在线一区二区| av不卡免费看| 在线亚洲一区| 91成人精品| 亚洲少妇一区| 国产精品普通话对白| 免费精品国产| 国内精品99| 激情婷婷久久| 日韩精品第一区| 亚洲免费福利| 精品一区二区三区在线观看视频| 精品伊人久久久| 你懂的国产精品| 国产精品xxx| 欧美91在线| 久久精品国产福利| 精品国产美女a久久9999| 中文字幕成人| 国产精品magnet| 免费亚洲一区| 久久91视频| 另类专区亚洲| 久久精品青草| 欧美一区久久久| 精品一区二区三区免费看| 国产资源在线观看入口av| 欧洲av不卡| 一区在线视频观看| 综合五月婷婷| 国产日产一区| 成人在线超碰| www在线观看黄色| 日韩午夜av在线| 免费不卡在线观看| 日本成人在线一区| 欧美激情精品| 91嫩草亚洲精品| 久久久精品午夜少妇| 精品一区三区| 亚洲在线久久| 国产精品欧美一区二区三区不卡| 国产精品亲子伦av一区二区三区| 久久精品国产久精国产爱| а√天堂8资源在线| 欧美精品一区二区久久| 石原莉奈在线亚洲三区| 欧美欧美黄在线二区| 久久久久久色 | 久久精品亚洲一区二区| 中文字幕成在线观看| 国产一区二区三区成人欧美日韩在线观看 | 欧洲毛片在线视频免费观看| 日韩视频在线一区二区三区 | 欧美久久天堂| 四虎国产精品免费久久| 久久av日韩| 久久久久91| 亚洲精品伊人|