国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Guava Cache介紹-面試用

這篇具有很好參考價(jià)值的文章主要介紹了Guava Cache介紹-面試用。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、Guava Cache簡(jiǎn)介

1、簡(jiǎn)介

Guava Cache是本地緩存,數(shù)據(jù)讀寫都在一個(gè)進(jìn)程內(nèi),相對(duì)于分布式緩存redis,不需要網(wǎng)絡(luò)傳輸?shù)倪^(guò)程,訪問(wèn)速度很快,同時(shí)也受到 JVM 內(nèi)存的制約,無(wú)法在數(shù)據(jù)量較多的場(chǎng)景下使用。

基于以上特點(diǎn),本地緩存的主要應(yīng)用場(chǎng)景為以下幾種:

  1. 對(duì)于訪問(wèn)速度有較大要求
  2. 存儲(chǔ)的數(shù)據(jù)不經(jīng)常變化
  3. 數(shù)據(jù)量不大,占用內(nèi)存較小
  4. 需要訪問(wèn)整個(gè)集合
  5. 能夠容忍數(shù)據(jù)不是實(shí)時(shí)的

2、對(duì)比

二、Guava Cache使用

下面介紹如何使用
1、先引入jar

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>27.0-jre</version>
</dependency>

案例1

1、創(chuàng)建Cache對(duì)象,在使用中,我們只需要操作loadingCache對(duì)象就可以了。

LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
        .initialCapacity(5)//內(nèi)部哈希表的最小容量,也就是cache的初始容量。
        .concurrencyLevel(3)//并發(fā)等級(jí),也可以定義為同時(shí)操作緩存的線程數(shù),這個(gè)影響segment的數(shù)組長(zhǎng)度,原理是當(dāng)前數(shù)組長(zhǎng)度為1如果小于并發(fā)等級(jí)且素組長(zhǎng)度乘以20小于最大緩存數(shù)也就是10000,那么數(shù)組長(zhǎng)度就+1,依次循環(huán)
        .maximumSize(10000)//cache的最大緩存數(shù)。應(yīng)該是數(shù)組長(zhǎng)度+鏈表上所有的元素的總數(shù)
        .expireAfterWrite(20L, TimeUnit.SECONDS)//過(guò)期時(shí)間,過(guò)期就會(huì)觸發(fā)load方法
        .build(new CacheLoader<String, String>() {
            @Override
            public String load(String key) {
                //緩存不存在,會(huì)進(jìn)到load方法,該方法返回值就是最終要緩存的數(shù)據(jù)。
                log.info("進(jìn)入load緩存");
                return "手機(jī)號(hào)";
            }
        });

2、通過(guò)緩存獲取數(shù)據(jù)

//獲取緩存,如果數(shù)據(jù)不存在,觸發(fā)load方法。
loadingCache.get(key);

案例2:使用reload功能

1、生成緩存對(duì)象

ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());

LoadingCache<String, String> loadingCache = CacheBuilder.newBuilder()
        .initialCapacity(5)
        .concurrencyLevel(3)
        .maximumSize(10000)
        .expireAfterWrite(20L, TimeUnit.SECONDS)//超這個(gè)時(shí)間,觸發(fā)的是load方法
        .refreshAfterWrite(5L, TimeUnit.SECONDS) //刷新,超過(guò)觸發(fā)的是reload方法
        //.expireAfterAccess(...): //當(dāng)緩存項(xiàng)在指定的時(shí)間段內(nèi)沒(méi)有被讀或?qū)懢蜁?huì)被回收。
        .build(new CacheLoader<String, String>() {
            @Override
            public String load(String key) {
                //緩存不存在或者緩存超過(guò)expireAfterWrite設(shè)置的時(shí)間,進(jìn)到load方法
                log.info("進(jìn)入load緩存");
                return "手機(jī)號(hào)";
            }

            @Override
            public ListenableFuture<String> reload(String key, String oldValue) throws Exception {
                //超過(guò)refreshAfterWrite時(shí)間,但是沒(méi)有超過(guò)expireAfterWrite時(shí)間,進(jìn)到reload方法
                log.info("進(jìn)入reload緩存");
				
                //這里是異步執(zhí)行任務(wù)
                return executorService.submit(() ->  {
                    Thread.sleep(1000L);
                    return "relad手機(jī)號(hào)";
                });
            }
        });

1、expireAfterWrite、refreshAfterWrite可以同時(shí)一起使用當(dāng)然,不同組合應(yīng)對(duì)不同場(chǎng)景。
2、需要說(shuō)明,當(dāng)緩存時(shí)間當(dāng)超過(guò)refreshAfterWrite時(shí)間,但是小于expireAfterWrite設(shè)置的時(shí)間,請(qǐng)求進(jìn)來(lái)執(zhí)行的是reload方法,當(dāng)時(shí)間超過(guò)expireAfterWrite時(shí)間,那么執(zhí)行的是load方法。

2、使用緩存對(duì)象

String value = loadingCache.get(key); //獲取緩存
loadingCache.invalidate(key); //刪除具體某個(gè)key的緩存
loadingCache.invalidateAll(Arrays.asList("key1","key2","key3"));//刪除多個(gè)
loadingCache.invalidateAll(); //刪除所有

三、源碼

緩存對(duì)象底層是LocalLoadingCache類,里面有個(gè)很重要的屬性segments,緩存數(shù)據(jù)都存在這個(gè)里面

//1、緩存對(duì)象
LocalLoadingCache{
	//segments是一個(gè)數(shù)組,每一個(gè)元素都是Segment類型
	final Segment<K, V>[] segments;	
}

//2、下面介紹下Segment這個(gè)類有哪些重要的屬性
class Segment<K, V> extends ReentrantLock{ //繼承了重入鎖
	//首先Segment里面有一個(gè)屬性table,這個(gè)table是AtomicReferenceArray類型
	AtomicReferenceArray<ReferenceEntry<K, V>> table;
}

//3、下面看下AtomicReferenceArray到底有什么
AtomicReferenceArray{
	//其實(shí)就是包裹了一個(gè)數(shù)組。每個(gè)元素都ReferenceEntry類型
	private final Object[] array;
}

AtomicReferenceArray特別之處在于下

提供了可以原子讀取、寫入,底層引用數(shù)組的操作,并且還包含高級(jí)原子操作。比較特別的就是put操作,就是我們?cè)诮o該數(shù)組某個(gè)元素設(shè)置值的時(shí)候可以使用比較的方式來(lái)設(shè)置值。
例如:AtomicReferenceArray.compareAndSet(2,10,20)
2下標(biāo)位置,10是新的值,20是原來(lái)期望的值,只有原來(lái)的值為20才會(huì)更新為10。

在回到上面AtomicReferenceArray里面的屬性array里面每一個(gè)元素都是ReferenceEntry類型,ReferenceEntry的實(shí)現(xiàn)類是StrongAccessWriteEntry

StrongAccessWriteEntry{
	final K key;
	//value存到了ValueReference對(duì)象里面,只是ValueReference包裝了一下,這個(gè)在并發(fā)的時(shí)候會(huì)用到。
	volatile ValueReference<K, V> value; 
	final int hash;
	final ReferenceEntry<K, V> next;    //針對(duì)hash碰撞時(shí)拓展的鏈表。	
}

結(jié)構(gòu)圖如下:

Guava Cache介紹-面試用,緩存框架,guava,cache,過(guò)期策略

四、下面介紹常用功能及其原理

1、獲取數(shù)據(jù)

1、通過(guò)key生成hash,根據(jù)hash從segments這個(gè)數(shù)組中得到具體下標(biāo),該元素是Segment類型
2、從Segment里面的table里面獲取,也就是AtomicReferenceArray的array從里面獲取數(shù)據(jù),此時(shí)拿到的是一個(gè)key所對(duì)應(yīng)的StrongAccessWriteEntry對(duì)象。
3、StrongAccessWriteEntry里面會(huì)存下該hash碰撞所對(duì)應(yīng)的其他key-value數(shù)據(jù)集合,StrongAccessWriteEntry對(duì)象保存了這個(gè)元素所對(duì)應(yīng)的hash,key,和value,next,還有過(guò)期時(shí)間,如果過(guò)期了也會(huì)返回return, 如果沒(méi)有過(guò)期,會(huì)進(jìn)行key對(duì)比,只有一致才會(huì)返回。
4、獲取的時(shí)候,如果數(shù)據(jù)不存在就會(huì)調(diào)用下面的put方法。獲取數(shù)據(jù)時(shí)是不使用lock()的。

2、put數(shù)據(jù)

在put前先lock(),為什么可以使用鎖,因?yàn)槔^承了ReentrantLock

Segment<K, V> extends ReentrantLock {
	.....
}

首先是通過(guò)Load方法拿到數(shù)據(jù),拿到后再通過(guò)storeLoadedValue方法來(lái)把結(jié)果寫到緩存數(shù)據(jù)里面去,在寫入的時(shí)候,也是用到了鎖lock(); 所以這里就雙重鎖了。
先是通過(guò)hash結(jié)合算法,得到下標(biāo),在根據(jù)下標(biāo)從AtomicReferenceArray數(shù)組中獲取元素,那么這個(gè)元素ReferenceEntry是一個(gè)有next的鏈表,所以我們要遍歷,這個(gè)鏈表,如果有key一致的,我么就要把他覆蓋掉。如果沒(méi)有就使用set方法設(shè)置值。

3、刪除數(shù)據(jù)

刪除數(shù)據(jù)也是一樣,先lock();
拿到找到這個(gè)元素所在的位置,然后刪除掉

4、過(guò)期策略(重點(diǎn))

過(guò)期配置主要包含著三個(gè)expireAfterWrite、refreshAfterWrite、expireAfterAccess,下面分別介紹下這個(gè)三個(gè)作用

expireAfterWrite:當(dāng)緩存項(xiàng)在指定時(shí)間后就會(huì)被回收(主動(dòng)),需要等待獲取新值才會(huì)返回。
expireAfterAccess: 當(dāng)緩存項(xiàng)在指定的時(shí)間段內(nèi)沒(méi)有被讀或?qū)懢蜁?huì)被回收。
refreshAfterWrite:設(shè)置緩存刷新時(shí)間。舉個(gè)例子:第一次請(qǐng)求進(jìn)來(lái),執(zhí)行l(wèi)oad把數(shù)據(jù)加載到內(nèi)存中(同步過(guò)程),假設(shè)指定的刷新時(shí)間是10秒,前10秒內(nèi)都是從cache里讀取數(shù)據(jù)。過(guò)了10秒后,沒(méi)有請(qǐng)求進(jìn)來(lái),不會(huì)移除key。再有請(qǐng)求過(guò)來(lái),才則執(zhí)行reload(異步調(diào)用),在后臺(tái)異步刷新的過(guò)程中,所以本次訪問(wèn)到的是舊值。刷新過(guò)程中只有一個(gè)線程在執(zhí)行刷新操作,不會(huì)出現(xiàn)多個(gè)線程同時(shí)刷新同一個(gè)key的緩存。在吞吐量很低的情況下,如很長(zhǎng)一段時(shí)間內(nèi)沒(méi)有請(qǐng)求,再次請(qǐng)求有可能會(huì)得到一個(gè)舊值(這個(gè)舊值可能還是很久之前的數(shù)據(jù)),這就會(huì)有問(wèn)題。(可以使用expireAfterWrite和refreshAfterWrite搭配使用解決這個(gè)問(wèn)題)。在設(shè)置了expireAfterWrite后,如果超過(guò)expire時(shí)間,走的就是load方法,這是實(shí)時(shí)去獲取數(shù)據(jù)。

//是否更新過(guò)期時(shí)間判斷條件,只要?jiǎng)?chuàng)建緩存對(duì)象時(shí)設(shè)置了"刷新時(shí)間"、"過(guò)期時(shí)間"都會(huì)更新時(shí)間
void recordWrite(ReferenceEntry<K, V> entry, int weight, long now) {
    drainRecencyQueue();
    totalWeight += weight;

    if (map.recordsAccess()) {    //這個(gè)判斷條件是expireAfterAccess>0
        entry.setAccessTime(now);   //設(shè)置過(guò)期時(shí)間
    }
    if (map.recordsWrite()) {        //這個(gè)判斷條件是expireAfterWrite>0
        entry.setWriteTime(now);   //設(shè)置過(guò)期時(shí)間
    }
    accessQueue.add(entry);
    writeQueue.add(entry);
}

如果存在設(shè)置了expireAfterAccess時(shí)間每次讀的時(shí)候,都會(huì)更新過(guò)期時(shí)間

if (map.recordsAccess()) {
    entry.setAccessTime(now);
}

那么在獲取數(shù)據(jù)的時(shí)候,是如何判斷是否執(zhí)行reload的,源碼里面有明確的判斷

V scheduleRefresh(ReferenceEntry<K, V> entry, K key, int hash, V oldValue, long now, CacheLoader<? super K, V> loader) {
    if (map.refreshes() && (now - entry.getWriteTime() > map.refreshNanos)) {
        V newValue = refresh(key, hash, loader, true);
    }
}
//map.refreshes()主要是判斷 refreshNanos > 0
//也就是代碼中build的refreshAfterWrite(2L, TimeUnit.MINUTES)代碼。設(shè)置了refreshNanos的時(shí)間。

場(chǎng)景1: 當(dāng)前時(shí)間減去緩存到期時(shí)間結(jié)果大于過(guò)期時(shí)間,才會(huì)執(zhí)行refresh方法,就會(huì)從reload里面獲取數(shù)據(jù)。
場(chǎng)景2:當(dāng)然還有一種情況就是既設(shè)置了refreshAfterWrite,又設(shè)置了expireAfterWrite,這個(gè)情況是,優(yōu)先判斷,數(shù)據(jù)是否過(guò)期了,如果并且過(guò)期時(shí)間超了,那么就執(zhí)行l(wèi)oad方法,如果沒(méi)有超過(guò)過(guò)期時(shí)間,超過(guò)了refresh的過(guò)期時(shí)間,那么就執(zhí)行reload方法,代碼如下

//判斷是否過(guò)期
if (map.isExpired(entry, now)) {
    return null;
}
//看下isExpired的邏輯
boolean isExpired(ReferenceEntry<K, V> entry, long now) {
	//這里忽略
    if (expiresAfterAccess() && (now - entry.getAccessTime() >= expireAfterAccessNanos)) {
        return true;
    }
    //判斷是否設(shè)置了expireAfterWriteNanos時(shí)間,且當(dāng)前時(shí)間減去過(guò)期時(shí)間是否超過(guò)expireAfterWriteNanos,超過(guò)則說(shuō)明數(shù)據(jù)已經(jīng)過(guò)期了。
    if (expiresAfterWrite() && (now - entry.getWriteTime() >= expireAfterWriteNanos)) {
        return true;
    }
    return false;
}

2、解決緩存擊穿

緩存擊穿:假如在緩存過(guò)期的那一瞬間,有大量的并發(fā)請(qǐng)求過(guò)來(lái)。他們都會(huì)因緩存失效而去加載執(zhí)行db操作,可能會(huì)給db造成毀滅性打擊。

解決方案: 采用expireAfterWrite+refreshAfterWrite 組合設(shè)置來(lái)防止緩存擊穿,expire則通過(guò)一個(gè)加鎖的方式,只允許一個(gè)線程去回源,有效防止了緩存擊穿,但是可以從源代碼看出,在有效防止緩存擊穿的同時(shí),會(huì)發(fā)現(xiàn)多線程的請(qǐng)求同樣key的情況下,一部分線程在waitforvalue,而另一部分線程在reentantloack的阻塞中。

//當(dāng)數(shù)據(jù)過(guò)期了,先拿到數(shù)據(jù)的狀態(tài),如果是正在執(zhí)行l(wèi)oad方法,則其他線程就先等待,
ValueReference<K, V> valueReference = e.getValueReference();
if (valueReference.isLoading()) {
    return waitForLoadingValue(e, key, valueReference);
}
//關(guān)鍵在于valueReference對(duì)象,他有2種兩類,不同類型代表不同狀態(tài)。

1、一開始創(chuàng)建的時(shí)候valueReference是LoadingValueReference類型對(duì)象。這個(gè)在剛創(chuàng)建entity的時(shí)候會(huì)用到。也就是load方法被執(zhí)行前LoadingValueReference固定是返回true

2、當(dāng)load方法被加載完valueReference類型就變成StrongValueReference。load執(zhí)行完后,更新entity的類型。StrongValueReference的isLoading方法固定是false
3、當(dāng)數(shù)據(jù)過(guò)期時(shí)

3、刷新時(shí)拿到的不一定是最新數(shù)據(jù)

因?yàn)槿绻驗(yàn)檫^(guò)期執(zhí)行刷新的方法也就是reload方法,那么從緩存里面拿到的數(shù)據(jù)不一定是新數(shù)據(jù),可能是老數(shù)據(jù),為什么,因?yàn)樗⑿聲r(shí)異步觸發(fā)reload,不像load同步這種,源碼如果reload的返回null,那么會(huì)優(yōu)先使用oldValue數(shù)據(jù)。

V scheduleRefresh(ReferenceEntry<K, V> entry, K key, int hash, V oldValue, long now, CacheLoader<? super K, V> loader) {
    if (map.refreshes() && (now - entry.getWriteTime() > map.refreshNanos)) {
        V newValue = refresh(key, hash, loader, true); //執(zhí)行刷新的方法,也就reload方法,下面看下refresh做了什么操作
        if (newValue != null) {
            return newValue;
        }
    }
    return oldValue;
}

refresh(K key, int hash, CacheLoader<? super K, V> loader, boolean checkTime) {
    //通過(guò)異步去執(zhí)行reload方法,注意是異步,此時(shí)沒(méi)有完成,那么直接返回null,那么上面的scheduleRefresh方法直接返回的是oldValue,也就是老數(shù)據(jù)。
    ListenableFuture<V> result = loadAsync(key, hash, loadingValueReference, loader);
    if (result.isDone()) {
        try {
            return Uninterruptibles.getUninterruptibly(result);
        } catch (Throwable t) {

        }
    }
    return null;
}

所以緩存失效第一次數(shù)據(jù)不一定是最新的數(shù)據(jù)??赡苁抢系臄?shù)據(jù),因?yàn)槭钱惒綀?zhí)行reload方法不知道耗時(shí)會(huì)有多久,所以主線程不會(huì)一直去等子線程完成。關(guān)注下,主線程在子線程執(zhí)行reload會(huì)等多久?

4、總結(jié)

1、refreshAfterWrites是異步去刷新緩存的方法,可能會(huì)使用過(guò)期的舊值快速響應(yīng)。

2、expireAfterWrites緩存失效后線程需要同步等待加載結(jié)果,可能會(huì)造成請(qǐng)求大量堆積的問(wèn)題。

四、注意點(diǎn)

在重寫load的時(shí)候,如果數(shù)據(jù)是空要寫成"",不能是null,因?yàn)樵趐ut的時(shí)候,會(huì)判斷返回的值如果是null就會(huì)拋出下面異常文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-731863.html

@Override
public String load(String key) {
    return ...
}

//當(dāng)load返回為空時(shí)會(huì)拋出異常
if (value == null) {
  throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + ".");
}

到了這里,關(guān)于Guava Cache介紹-面試用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • flink1.15 維表join guava cache和mysql方面優(yōu)化

    flink1.15 維表join guava cache和mysql方面優(yōu)化

    優(yōu)化前? mysql響應(yīng)慢,導(dǎo)致算子中數(shù)據(jù)輸出追不上輸入,導(dǎo)致顯示cpu busy:100% 優(yōu)化后效果兩個(gè)圖對(duì)應(yīng)兩個(gè)時(shí)刻: - - 圖中g(shù)uava cache命中率是通過(guò)guava自帶統(tǒng)計(jì),打印出來(lái)的. 1 guava緩存數(shù)據(jù)量上限?= 類中配置的guava緩存數(shù)據(jù)上線 * task個(gè)數(shù)(即flink并行度) 緩存越久 命中率越高 數(shù)據(jù)越陳舊

    2024年01月17日
    瀏覽(24)
  • Spring Cache框架(緩存)

    1、介紹: Spring Cache 是一個(gè)框架,實(shí)現(xiàn)了基于注解的緩存功能,只需要簡(jiǎn)單加個(gè)注解,就能實(shí)現(xiàn)緩存功能。它提供了一層抽象,底層可以切換不同的cache實(shí)現(xiàn)。具體就是通過(guò) CacheManager 接口來(lái)實(shí)現(xiàn)不同的緩存技術(shù)。 針對(duì)不同的混存技術(shù)需要實(shí)現(xiàn)不同的 CacheManage r: CacheManager 描述

    2024年02月11日
    瀏覽(30)
  • Spring | Spring Cache 緩存框架

    Spring | Spring Cache 緩存框架

    Spring Cache 是 Spring 的一個(gè)框架, 實(shí)現(xiàn)了基于注解的緩存功能 。只需簡(jiǎn)單加一個(gè) 注解 ,就能實(shí)現(xiàn) 緩存功能 。 Spring Cache提供了一層抽象 , 底層可以切換不同的緩存實(shí)現(xiàn) 。比較 常見 的(底層) 緩存實(shí)現(xiàn) 有: Redis、EHCache、Caffeine ??勺远x地修改 Spring Cache 底層的 緩存實(shí)現(xiàn) 。

    2024年02月08日
    瀏覽(19)
  • Google的guava緩存學(xué)習(xí)使用

    導(dǎo)入依賴 使用1 項(xiàng)目中使用到了緩存,定義一個(gè)切面,攔截類或方法上存在@SysDataCache注解請(qǐng)求,對(duì)于這些方法的返回值進(jìn)行緩存。項(xiàng)目中主要還是使用在緩存常量,一些不易改變的值 定義注解 定義切面和初始化緩存容器并使用緩存 項(xiàng)目中緩存使用 使用2 作為性能緩存工具,

    2024年01月25日
    瀏覽(25)
  • 【java緩存、redis緩存、guava緩存】java中實(shí)現(xiàn)緩存的幾種方式

    【java緩存、redis緩存、guava緩存】java中實(shí)現(xiàn)緩存的幾種方式

    這種方式可以簡(jiǎn)單實(shí)現(xiàn)本地緩存,但是實(shí)際開發(fā)中不推薦使用,下面我們來(lái)實(shí)現(xiàn)一下這種方式。 首先創(chuàng)建一個(gè)管理緩存的類 這個(gè)類中有一個(gè)靜態(tài)代碼塊,靜態(tài)代碼塊會(huì)在類加載時(shí)就執(zhí)行,我們可以在這里完成對(duì)緩存的初始化,決定緩存內(nèi)一開始就有哪些數(shù)據(jù) 另外我們還可以

    2024年02月16日
    瀏覽(15)
  • 【Redis(8)】Spring Boot整合Redis和Guava,解決緩存穿透、緩存擊穿、緩存雪崩等緩存問(wèn)題

    在緩存技術(shù)的挑戰(zhàn)及設(shè)計(jì)方案我們介紹了使用緩存技術(shù)可能會(huì)遇到的一些問(wèn)題,那么如何解決這些問(wèn)題呢? 在構(gòu)建緩存系統(tǒng)時(shí),Spring Boot和Redis的結(jié)合提供了強(qiáng)大的支持,而Guava的 LoadingCache 則為緩存管理帶來(lái)了便捷的解決方案。下面我將介紹如何通過(guò)整合Spring Boot、Redis和Gu

    2024年04月22日
    瀏覽(24)
  • 【譯】Google Guava 的 Table 接口介紹

    【譯】Google Guava 的 Table 接口介紹

    原文:https://www.baeldung.com/guava-table 在本教程中,我們將展示如何使用 Google Guava 的 Table 接口及其多個(gè)實(shí)現(xiàn)。 Guava 的 Table 是一種集合,表示包含行、列和相關(guān)單元格值的表結(jié)構(gòu),行和列充當(dāng)有序的鍵對(duì)。 讓我們看看如何使用 Table 類。 2.1. Maven依賴 首先,在 pom.xml 中添加 Goo

    2024年02月06日
    瀏覽(26)
  • 重試框架入門:Spring-Retry&Guava-Retry

    重試框架入門:Spring-Retry&Guava-Retry

    在日常工作中,隨著業(yè)務(wù)日漸龐大,不可避免的涉及到調(diào)用遠(yuǎn)程服務(wù),但是遠(yuǎn)程服務(wù)的健壯性和網(wǎng)絡(luò)穩(wěn)定性都是不可控因素,因此,我們需要考慮合適的重試機(jī)制去處理這些問(wèn)題,最基礎(chǔ)的方式就是手動(dòng)重試,侵入業(yè)務(wù)代碼去處理,再高端一點(diǎn)的通過(guò)切面去處理,較為優(yōu)雅的

    2024年02月13日
    瀏覽(57)
  • SpringBoot Cache緩存

    application.properties配置文件 ehcache.xml配置文件 name:cache的名字,必須惟一。 eternal:是否持久化,若為true,則表示緩存元素不會(huì)過(guò)期。 maxElementsInMemory:cache中最多可以存放的元素的數(shù)量。 overflowToDisk:溢出是否寫入磁盤。 diskPersistent:是否持久化磁盤緩存。 timeToIdleSeconds:訪

    2024年01月18日
    瀏覽(42)
  • Buffer(緩沖)、Cache(緩存)

    Buffer 用途:緩沖通常用于臨時(shí)存儲(chǔ)數(shù)據(jù),以平衡不同速度的數(shù)據(jù)傳輸過(guò)程直接的差異。它可以用來(lái)解決數(shù)據(jù)傳輸速度不匹配的問(wèn)題。 例如: 當(dāng)您在觀看視頻時(shí),視頻播放器會(huì)緩沖一段時(shí)間的視頻數(shù)據(jù),以便在網(wǎng)絡(luò)速度慢或不穩(wěn)定的情況下也能夠流暢的播放 用完之后,就清除

    2024年02月03日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包