最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?guava框架LoadingCache及CacheBuilder本地小容量緩存框架總結(jié)

 更新時(shí)間:2023年12月22日 11:56:09   作者:極光雨雨  
Guava?Cache本地緩存框架主要是一種將本地?cái)?shù)據(jù)緩存到內(nèi)存中,但數(shù)據(jù)量并不能太大,否則將會(huì)占用過多的內(nèi)存,本文給大家介紹Java?guava框架?LoadingCache及CacheBuilder?本地小容量緩存框架總結(jié),感興趣的朋友一起看看吧

Guava Cache本地緩存框架介紹

主要是一種將本地?cái)?shù)據(jù)緩存到內(nèi)存中,但數(shù)據(jù)量并不能太大,否則將會(huì)占用過多的內(nèi)存,雖然框架本身已經(jīng)做了相當(dāng)?shù)臄?shù)據(jù)回收,但還是不可以濫用,需要符合以下優(yōu)點(diǎn)場(chǎng)景,才是合適使用,訪問內(nèi)存的速度快于訪問 redis 等數(shù)據(jù)庫(kù)。

有點(diǎn)以及需求場(chǎng)景:

  • 對(duì)性能有非常高的要求
  • 愿意消耗一些內(nèi)存空間來提升速度
  • 預(yù)計(jì)到某些鍵會(huì)被多次查詢
  • 緩存中存放的數(shù)據(jù)總量不會(huì)超出內(nèi)存容量

關(guān)鍵點(diǎn)是:有頻繁訪問的數(shù)據(jù),且這些數(shù)據(jù)本身占用內(nèi)存量很少,將這些數(shù)據(jù)存儲(chǔ)到該緩存框架中管理以提供性能。

提供的優(yōu)勢(shì)能力

  • 緩存可以設(shè)置過期時(shí)間,并提供數(shù)據(jù)過多時(shí)的淘汰機(jī)制
  • 是線程安全的,支持并發(fā)讀入和寫入
  • 緩存獲取不到時(shí)可以從數(shù)據(jù)源獲取并加入到緩存中,GuavaCache 可以使用 CacheLoader 的load 方法控制,對(duì)同一個(gè)key,只允許一個(gè)請(qǐng)求去讀源并回填緩存,其他請(qǐng)求阻塞等待
  • 可以查看緩存的加載獲取信息等

使用以及方法

Maven 依賴:

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>

最簡(jiǎn)單的構(gòu)建案例

Cache<String, Object> cache = CacheBuilder.newBuilder().build();
cache.put("aaa", 156484);

Map類似,獲取時(shí)使用get() 方法即可獲取到放入其中的數(shù)據(jù)。

通過 CacheBuilder 創(chuàng)建 Cache 對(duì)象,存儲(chǔ)類似于Map 構(gòu)建方法為鏈?zhǔn)綐?gòu)造,類似于 builder 建造者模式,返回均為當(dāng)前對(duì)象本身,調(diào)用 build 方法后結(jié)束構(gòu)造。

CacheBuilder.newBuilder() 后的一些構(gòu)建參數(shù)方法介紹:

initialCapacity:緩存的初始數(shù)據(jù)容量大小,一般要貼合實(shí)際否則會(huì)造成資源浪費(fèi)
maximumSize:緩存中可包含最大 entry 數(shù)量,超過數(shù)量限制后淘汰 entry,接近最大值時(shí)淘汰不常用數(shù)據(jù),設(shè)置為 0 時(shí)為不使用緩存的場(chǎng)景,用于測(cè)試數(shù)據(jù)加載

過期時(shí)間設(shè)置

expireAfterAccess:數(shù)據(jù)寫入后被訪問對(duì)象多久沒被訪問認(rèn)為過期
expireAfterWrite: 數(shù)據(jù)被寫入到緩存后一直未更新多久后過期

可以如下寫:

        Cache<String, Object> cache = CacheBuilder.newBuilder()
                .initialCapacity(5)
                .maximumSize(10)
                .expireAfterWrite(10, TimeUnit.MINUTES).build();
		cache.put("154", "djawbdawd");

過期時(shí)間單位通過 TimeUnit 后的控制,時(shí)分秒均可

弱軟引用 (weakKeys, weakValues, softValues)

weakKeys
將緩存中的key設(shè)置成weakKey模式。
默認(rèn)情況下,會(huì)使用“強(qiáng)關(guān)系”來保存key值。當(dāng)設(shè)置為weakKey時(shí),會(huì)使用 “==” 來匹配key值。在使用weakKey的情況下,數(shù)據(jù)可能會(huì)被GC。數(shù)據(jù)被GC后,可能仍然會(huì)被size方法計(jì)數(shù),但是對(duì)其執(zhí)行read或write方法已經(jīng)無效。

weakValues
將緩存中的數(shù)據(jù)設(shè)置為weakValues模式。
啟用時(shí),某些數(shù)據(jù)會(huì)被GC。默認(rèn)情況下會(huì)使用“強(qiáng)關(guān)系”來保存key值。當(dāng)設(shè)置為weakValue時(shí),會(huì)使用 “==” 來匹配value值。數(shù)據(jù)被GC后,可能仍然會(huì)被size方法計(jì)數(shù),但是對(duì)其執(zhí)行read或write方法已經(jīng)無效。

softValues
將緩存中的數(shù)據(jù)設(shè)置為softValues模式。
啟用時(shí),所有的數(shù)據(jù)都使用SoftReference類對(duì)緩存中的數(shù)據(jù)進(jìn)行包裹(就是在SoftReference實(shí)例中存儲(chǔ)真實(shí)的數(shù)據(jù))。使用SoftReference包裹的數(shù)據(jù),會(huì)被全局垃圾回收管理器托管,按照LRU的原則來定期GC數(shù)據(jù)。數(shù)據(jù)被GC后,可能仍然會(huì)被size方法計(jì)數(shù),但是對(duì)其執(zhí)行read或write方法已經(jīng)無效。

這些同樣在 CacheBuilder.newBuilder() 后設(shè)置。

主動(dòng)刪除數(shù)據(jù)

當(dāng)通過 builder 創(chuàng)建對(duì)象完成后,可以通過以下方式清除數(shù)據(jù):
invalidateAll:清除全部數(shù)據(jù),入?yún)?Iterable 類型參數(shù),即 一般的List 集合即可,內(nèi)容為所有的 key
invalidate:?jiǎn)我粍h除,入?yún)?key

刪除監(jiān)聽器

即用于監(jiān)控緩存中的數(shù)據(jù),當(dāng)數(shù)據(jù)被刪除時(shí)會(huì)被觸發(fā)
類似如下代碼:

        RemovalListener<String, String> listener = new RemovalListener<String, Object>() {
            public void onRemoval(RemovalNotification<String, String> notification) {
            // notification.getKey();  // 當(dāng)前刪除對(duì)象的 key
            // notification.getValue();  // 當(dāng)前刪除對(duì)象的 value
            }
        };
        Cache<String, Object> cache = CacheBuilder.newBuilder()
                .maximumSize(5)
                // 添加移除監(jiān)聽器
                .removalListener(listener) 
                .build();

值得注意的是,這里的刪除不僅是主動(dòng)刪除,當(dāng)達(dá)到容量上限或者過期或由于其他策略導(dǎo)致數(shù)據(jù)消失時(shí)也認(rèn)為是刪除

一般cache 主動(dòng)加載數(shù)據(jù)

即當(dāng)緩存中獲取不到指定 key 對(duì)應(yīng)的 value 時(shí),需要主動(dòng)去其他途徑獲取:

寫法類似如下,需要提供獲取的實(shí)現(xiàn)方法:

Cache<String, Object> cache = CacheBuilder.newBuilder()
                .initialCapacity(5)
                .maximumSize(10)
                .expireAfterWrite(10, TimeUnit.MINUTES).build();
        cache.put("154", "djawbdawd");
        try {
            cache.get("aaa", new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    // 具體如何獲取
                    // 方法的返回值即為 當(dāng)前key 對(duì)應(yīng)的value 并將會(huì)加入到緩存中
                    return null;
                }
            });
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

需要在 Callable 內(nèi)的方法重寫獲取實(shí)際數(shù)據(jù)的方法,方法的返回值即為 當(dāng)前key 對(duì)應(yīng)的value 并將會(huì)加入到緩存中,同時(shí)如果存在多個(gè)線程同時(shí)獲取同一個(gè)不存在的 key,那么將只有一個(gè)被執(zhí)行,其他需要等待。且一個(gè)線程獲取后,其他線程將也可以獲取這些數(shù)據(jù)。

統(tǒng)計(jì)信息

創(chuàng)建cache 對(duì)象時(shí)調(diào)用**.recordStats()** 后將開啟統(tǒng)計(jì),可以通過 cache.stats() 獲取緩存
例如:

        Cache<String, Object> cache = CacheBuilder.newBuilder()
                .initialCapacity(5)
                .maximumSize(10)
                .recordStats()
                .expireAfterWrite(10, TimeUnit.MINUTES).build();
        cache.put("154", "djawbdawd");
        try {
            cache.get("aaa", new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    // .......
                    return null;
                }
            });
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        cache.stats();

較常用的 LoadingCache

LoadingCache 是 Cache的子接口 ,相比于Cache,當(dāng)從LoadingCache中讀取一個(gè)指定key的記錄時(shí),如果該記錄不存在,則LoadingCache可以自動(dòng)執(zhí)行加載數(shù)據(jù)到緩存的操作,定義時(shí)需要重寫加載方法。
LoadingCache接口的定義如下:

CacheLoader<String, String> loader = new CacheLoader<>() {
		// 加載沒有的數(shù)據(jù)的方法
            public String load(String key) throws Exception {
            // .............
                return null;
            }
        };
        LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
                .maximumSize(5)
                .build(loader);

或如下:

LoadingCache<String, Object> infoItemCache = CacheBuilder.newBuilder()
		.initialCapacity(5)
		.maximumSize(10)
		.expireAfterAccess(3, TimeUnit.MINUTES).build(new CacheLoader<String, Object>() {
                    // 使用 LoadingCache 重寫加載方法, 重寫后當(dāng)無法從緩存中獲取到key 對(duì)應(yīng)的值時(shí)將執(zhí)行重寫的load 方法,且返回值將成為入?yún)ey 對(duì)應(yīng)的Value并存儲(chǔ)
                    @Override
                    public Object load(String s) throws Exception {
                        // ............
                        return null;
                    }
                });

可以自定義簡(jiǎn)單工具如下:

import com.dtdream.dthink.dtalent.dmall.dataresource.catalog.model.metadata.MetadataBlock;
import com.dtdream.dthink.dtalent.dmall.dataresource.catalog.service.catalog.ICatalogTemplateService;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class MyCache {
    /**
     * 初始化緩存容量大小
     */
    private static final int INITIAL_CAPACITY = 5;
    /**
     * 緩存中可包含最大 entry 數(shù)量,超過數(shù)量限制后淘汰 entry,接近最大值時(shí)淘汰不常用數(shù)據(jù),設(shè)置為 0 時(shí)為不使用緩存的場(chǎng)景,用于測(cè)試數(shù)據(jù)加載
     */
    private static final long MAXIMUM_SIZE = 10;
    /**
     * 放入緩存后指定時(shí)間內(nèi)沒有被訪問將過期
     */
    private static final long EXPIRE_AFTER_ACCESS = 5;
    /**
     * cache 子接口, 緩存對(duì)象
     */
    private static LoadingCache<String, Object> infoItemCache;
    // 初始化緩存對(duì)象
    static {
        infoItemCache = CacheBuilder.newBuilder().initialCapacity(INITIAL_CAPACITY).maximumSize(MAXIMUM_SIZE)
                .expireAfterAccess(EXPIRE_AFTER_ACCESS, TimeUnit.MINUTES).build(new CacheLoader<String, Object>() {
                    // 使用 LoadingCache 重寫加載方法, 重寫后當(dāng)無法從緩存中獲取到key 對(duì)應(yīng)的值時(shí)將執(zhí)行重寫的load 方法,且返回值將成為入?yún)ey 對(duì)應(yīng)的Value并存儲(chǔ)
                    @Override
                    public Object load(String s) throws Exception {
                        // ...............
                        return null;
                    }
                });
    }
    /**
     * 從緩存中獲取數(shù)據(jù),若不存在則重新查詢
     * @return
     */
    public static Object getFromCache(String key) throws ExecutionException {
        Object data = infoItemCache.get(key);
        return data;
    }
}

若需要從Spring 獲取Bean 服務(wù),則可以通過 Spring 的 applicationConext 去獲取

到此這篇關(guān)于Java guava框架 LoadingCache,CacheBuilder 本地小容量緩存框架學(xué)習(xí)以及總結(jié)的文章就介紹到這了,更多相關(guān)Java guava框架 LoadingCache內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Spring @Autowired 注入小技巧

    詳解Spring @Autowired 注入小技巧

    這篇文章主要介紹了詳解Spring @Autowired 注入小技巧,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • SpringBoot無法解析parameter參數(shù)問題的解決方法

    SpringBoot無法解析parameter參數(shù)問題的解決方法

    使用最新版的 Springboot 3.2.1(我使用3.2.0)搭建開發(fā)環(huán)境進(jìn)行開發(fā),調(diào)用接口時(shí)出現(xiàn)奇怪的錯(cuò),本文小編給大家介紹了SpringBoot無法解析parameter參數(shù)問題的原因及解決方法,需要的朋友可以參考下
    2024-04-04
  • 劍指Offer之Java算法習(xí)題精講二叉樹與鏈表

    劍指Offer之Java算法習(xí)題精講二叉樹與鏈表

    跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例

    Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例

    這篇文章主要介紹了Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java?電話號(hào)碼的組合示例詳解

    Java?電話號(hào)碼的組合示例詳解

    這篇文章主要介紹了Java?電話號(hào)碼的組合,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Java均攤復(fù)雜度和防止復(fù)雜度的震蕩原理分析

    Java均攤復(fù)雜度和防止復(fù)雜度的震蕩原理分析

    這篇文章主要介紹了Java均攤復(fù)雜度和防止復(fù)雜度的震蕩,結(jié)合實(shí)例形式分析了Java均攤復(fù)雜度和防止復(fù)雜度的震蕩相關(guān)概念、原理、實(shí)現(xiàn)方法與注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • 詳解Java中NullPointerException異常的原因和解決辦法

    詳解Java中NullPointerException異常的原因和解決辦法

    本文主要介紹了詳解Java中NullPointerException異常的原因和解決辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • SpringBoot項(xiàng)目實(shí)現(xiàn)通過分詞器生成詞云

    SpringBoot項(xiàng)目實(shí)現(xiàn)通過分詞器生成詞云

    本文介紹了如何在SpringBoot項(xiàng)目中利用IK分詞器和Kumo庫(kù)生成員工任務(wù)的詞云圖,展示了從引入依賴、配置YAML到Controller中處理文本并生成詞云的詳細(xì)步驟以及處理中文文本的注意事項(xiàng),希望對(duì)大家有所幫助
    2026-05-05
  • Java數(shù)組看這篇就夠了

    Java數(shù)組看這篇就夠了

    這篇文章主要介紹了Java數(shù)組的詳細(xì)解釋,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • SpringBoot + Redis 實(shí)現(xiàn)API接口限流的幾種方法

    SpringBoot + Redis 實(shí)現(xiàn)API接口限流的幾種方法

    本文主要介紹了SpringBoot + Redis 實(shí)現(xiàn)API接口限流的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-01-01

最新評(píng)論

长丰县| 特克斯县| 青河县| 盐池县| 岳池县| 镇巴县| 巴楚县| 宜宾县| 延边| 邻水| 苏尼特右旗| 朝阳区| 阿瓦提县| 恭城| 贵港市| 大荔县| 阳谷县| 蕉岭县| 湖南省| 南漳县| 雷山县| 遂平县| 房山区| 潜山县| 嵩明县| 准格尔旗| 永德县| 东源县| 屏东县| 冕宁县| 沭阳县| 卢氏县| 黔南| 扬州市| 晋州市| 阳城县| 竹溪县| 灵山县| 湄潭县| 庄浪县| 新乡市|