亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java設(shè)置Map過期時間的的幾種方法舉例詳解

 更新時間:2024年10月14日 09:52:23   作者:虞澤  
本文詳細介紹了Java中使用輕量級緩存組件ExpiringMap以及Guava的LoadingCache緩存機制,ExpiringMap提供了Map自動過期、監(jiān)聽事件等功能,而LoadingCache提供了緩存回收、數(shù)據(jù)加載等高級功能,兩者為Java項目提供了有效的數(shù)據(jù)管理和緩存解決方案,需要的朋友可以參考下

一、技術(shù)背景

在實際的項目開發(fā)中,我們經(jīng)常會使用到緩存中間件(如redis、MemCache等)來幫助我們提高系統(tǒng)的可用性和健壯性。

但是很多時候如果項目比較簡單,就沒有必要為了使用緩存而專門引入Redis等等中間件來加重系統(tǒng)的復(fù)雜性。那么使用Java本身自己的輕量級的緩存組件就是完美解決方式。

二、技術(shù)效果

  • 實現(xiàn)緩存的常見功能
  • 熱點數(shù)據(jù)預(yù)熱
  • 簡單限流
  • 去重

三、ExpiringMap

3.1 ExpiringMap簡介

ExpiringMap具有高性能、低開銷、零依賴、線程安全、使用 ConcurrentMap 的實現(xiàn)過期 entries 等優(yōu)點。
功能包括不限于:

  • 設(shè)置 Map 中的 Entry 在一段時間后自動過期。
  • 設(shè)置 Map 最大容納值,當(dāng)?shù)竭_ Max size 后,再次插入值會導(dǎo)致 Map 中的第一個值過期。
  • 設(shè)置 添加監(jiān)聽事件,在監(jiān)聽到 Entry 過期時調(diào)度監(jiān)聽函數(shù)。
  • 設(shè)置懶加載,在調(diào)用 get() 方法時創(chuàng)建對象。
  • 允許您了解條目預(yù)計何時過期

3.2 ExpiringMap使用

3.2.1 pom.xml 中添加依賴

        <!-- https://mvnrepository.com/artifact/net.jodah/expiringmap -->
        <dependency>
            <groupId>net.jodah</groupId>
            <artifactId>expiringmap</artifactId>
            <version>0.5.10</version>
        </dependency>

3.2.2 代碼中使用

    /**
     * ① maxSize:Map存儲的最大值,類似隊列,容量固定,當(dāng)操作map容量超出限制時,最開始的元素就會依次過期,只保留最新的;
     * ② expiration:過期時間;
     * ③ expirationListener:過期監(jiān)聽,當(dāng)條目過期時,將同步調(diào)用過期偵聽器,并且在偵聽器完成之前,
     *  將阻止對映射的寫入操作。還可以在單獨的線程池中配置和調(diào)用異步過期偵聽器,而不會阻塞映射操作;
     * ④ expirationPolicy:過期策略,包括 ExpirationPolicy.ACCESSED 和 ExpirationPolicy.CREATED 兩種;
     *      1)ExpirationPolicy.ACCESSED :每進行一次訪問,過期時間就會自動清零,重新計算;
     *      2)ExpirationPolicy.CREATED:在過期時間內(nèi)重新 put 值的話,過期時間會清理,重新計算;
     * ⑤ variableExpiration:可變過期,條目可以具有單獨可變的到期時間和策略:
     */
    public static  ExpiringMap<String, String> map = ExpiringMap.builder()
            .maxSize(1000)
            .expiration(2, TimeUnit.HOURS)
            .variableExpiration()
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .expirationListener((key, value) -> {
                System.out.println("SseEmitter已過期,key:"+ key);
            })
            .build();

3.2.3 參數(shù)說明

 ① maxSize:Map存儲的最大值,類似隊列,容量固定,當(dāng)操作map容量超出限制時,最開始的元素就會依次過期,只保留最新的;
 ② expiration:過期時間;
 ③ expirationListener:過期監(jiān)聽,當(dāng)條目過期時,將同步調(diào)用過期偵聽器,并且在偵聽器完成之前,
  將阻止對映射的寫入操作。還可以在單獨的線程池中配置和調(diào)用異步過期偵聽器,而不會阻塞映射操作;
 ④ expirationPolicy:過期策略,包括 ExpirationPolicy.ACCESSED 和 ExpirationPolicy.CREATED 兩種;
           1)ExpirationPolicy.ACCESSED :每進行一次訪問,過期時間就會自動清零,重新計算;
           2)ExpirationPolicy.CREATED:在過期時間內(nèi)重新 put 值的話,過期時間會清理,重新計算;
 ⑤ variableExpiration:可變過期,條目可以具有單獨可變的到期時間和策略;

3.2.4 其他使用方式

		//為單個條目指定到期策略:
        map.put("1", "張三", ExpirationPolicy.CREATED);
        map.put("2", "李四", ExpirationPolicy.ACCESSED);

        //variableExpiration 可變過期 條目可以具有單獨可變的到期時間和策略:
        map.put("3", "王五", ExpirationPolicy.ACCESSED, 5, TimeUnit.MINUTES);

        //過期時間和策略也可以即時更改:
        map.setExpiration("1", 5, TimeUnit.MINUTES);
        map.setExpirationPolicy("1", ExpirationPolicy.ACCESSED);

        //動態(tài)添加和刪除過期偵聽器:
        ExpirationListener<String, String> connectionCloser = (key, value) -> System.out.println(key+":"+value);
        //添加偵聽器
        map.addExpirationListener(connectionCloser);
        //移除偵聽器
        map.removeExpirationListener(connectionCloser);

        //設(shè)置懶加載
//        Map<String, String> stringMap = ExpiringMap.builder()
//                .expiration(10, TimeUnit.MINUTES)
//                .entryLoader(address -> address)
//                .build();
//        // 通過 EntryLoader 將值加載到map中
//        String value = stringMap.get("1");
//        System.out.println("value值:"+value);

        //獲取條目的到期時間:單位:毫秒
        long expiration = map.getExpectedExpiration("1");
        System.out.println("距離過期時間還有:"+expiration+"毫秒");

        //重置條目的內(nèi)部到期計時器:
        map.resetExpiration("1");

        //查看設(shè)置的過期時間
        map.getExpiration("1");
        System.out.println("設(shè)置的過期時間:"+map.getExpiration("1"));
        

測試結(jié)果

距離過期時間還有:299999毫秒
設(shè)置的過期時間:300000

四、Guava的LoadingCache

4.1 LoadingCache簡介

做java的我們都知道Guava是一個編程工具類庫,其中包含了很多高質(zhì)量高性能的工具類和方法。其中,LoadingCache便是一個特別好用的功能,其背后的架構(gòu)其實就是Guava cache,Guava Cache 是一個全內(nèi)存的本地緩存實現(xiàn),它提供了線程安全的實現(xiàn)機制,它可以加載緩存中不存在的數(shù)據(jù),本質(zhì)其實是一個鍵值對(key-value)的緩存,可以通過key獲取到對應(yīng)的緩存值value。
特點:提供緩存回收機制,監(jiān)控緩存加載/命中情況,靈活強大的功能,簡單易上手的api。

4.2 LoadingCache使用

4.2.1 pom.xml 中添加依賴

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

4.2.2 代碼中使用

	public static LoadingCache<Long, User> userCache= CacheBuilder.newBuilder()
            // 緩存池大小,在緩存數(shù)量到達該大小時, 開始回收舊的數(shù)據(jù)
            .maximumSize(1000)
            // 設(shè)置時間60s對象沒有被讀/寫訪問則對象從內(nèi)存中刪除
            .expireAfterAccess(60, TimeUnit.SECONDS)
            // 設(shè)置緩存在寫入之后 設(shè)定時間60s后失效
            .expireAfterWrite(60, TimeUnit.SECONDS)
            // 定時刷新,設(shè)置時間10s后,當(dāng)有訪問時會重新執(zhí)行l(wèi)oad方法重新加載
            .refreshAfterWrite(10, TimeUnit.SECONDS)
            // 移除監(jiān)聽器,緩存項被移除時會觸發(fā)
            .removalListener(new RemovalListener() {
                @Override
                public void onRemoval(RemovalNotification rn) {
                    // 處理緩存鍵不存在緩存值時的處理邏輯
                    log.error(rn.getKey() + "remove");
                }
            })
            // 處理緩存鍵對應(yīng)的緩存值不存在時的處理邏輯
            .build(new CacheLoader<Long, User>() {
                @Override
                public User load(Long id) {
                    return getById(id);
                }
    });
 
    public User getUser(Long id) {
        User user = userCache.get(id);
    }
 
    public ImmutableMap<Long, User > getAll(List<Long> ids) throws ExecutionException {
        return cache.getAll(ids);
    }

4.2.3 參數(shù)說明

 ① maximumSize:緩存的k-v最大數(shù)據(jù),當(dāng)總緩存的數(shù)據(jù)量達到這個值時,就會淘汰它認為不太用的一份數(shù)據(jù),會使用LRU策略進行回收;
 ② expireAfterAccess:緩存項在給定時間內(nèi)沒有被讀/寫訪問,則回收,這個策略主要是為了淘汰長時間不被訪問的數(shù)據(jù);
 ③ expireAfterWrite:緩存項在給定時間內(nèi)沒有被寫訪問(創(chuàng)建或覆蓋),則回收, 防止舊數(shù)據(jù)被緩存過久;
 ④ refreshAfterWrite:緩存項在給定時間內(nèi)沒有被寫訪問(創(chuàng)建或覆蓋),則刷新;
 ⑤ recordStats:開啟Cache的狀態(tài)統(tǒng)計(默認是開啟的);

4.2.4 GET方法

  V get(K key, int hash, CacheLoader<? super K, V> loader) throws ExecutionException {
    try {
      if (count != 0) { // read-volatile
        ReferenceEntry<K, V> e = getEntry(key, hash);
        if (e != null) {
          long now = map.ticker.read();
          //檢查entry是否符合expireAfterAccess淘汰策略
          V value = getLiveValue(e, now);
          // value是有效的 則返回
          if (value != null) {
            // 記錄該值的最近訪問時間
            recordRead(e, now);
            statsCounter.recordHits(1);
            // 內(nèi)部實現(xiàn)了定時刷新,若未開啟refreshAfterWrite則直接返回value
            return scheduleRefresh(e, key, hash, value, now, loader);
          }
          ValueReference<K, V> valueReference = e.getValueReference();
          // 如果有別的線程已經(jīng)在load value,則等到其他線程完成后再取結(jié)果
          if (valueReference.isLoading()) {
            return waitForLoadingValue(e, key, valueReference);
          }
        }
      }
 
      // 如果沒拿到有效的value,則執(zhí)行加載邏輯;
      return lockedGetOrLoad(key, hash, loader);
    } catch (ExecutionException ee) {
      ...
    } finally {
      postReadCleanup();
    }
  }

4.2.5 Load方法

@GwtCompatible(emulated = true)
public abstract class CacheLoader<K, V> {
 
  public abstract V load(K key) throws Exception;
 
}

4.3 移除機制

guava做cache時候數(shù)據(jù)的移除分為被動移除和主動移除兩種。

  • 被動移除
  • 基于大小的移除:數(shù)量達到指定大小,會把不常用的鍵值移除
  • 基于時間的移除:expireAfterAccess(long, TimeUnit) 根據(jù)某個鍵值對最后一次訪問之后多少時間后移除。expireAfterWrite(long, TimeUnit) 根據(jù)某個鍵值對被創(chuàng)建或值被替換后多少時間移除
  • 基于引用的移除:主要是基于java的垃圾回收機制,根據(jù)鍵或者值的引用關(guān)系決定移除
  • 主動移除
  • 單獨移除:Cache.invalidate(key)
  • 批量移除:Cache.invalidateAll(keys)
  • 移除所有:Cache.invalidateAll()

如果配置了移除監(jiān)聽器RemovalListener,則在所有移除的動作時會同步執(zhí)行該listener下的邏輯。
如需改成異步,使用:RemovalListeners.asynchronous(RemovalListener, Executor)。

4.4 其他

  • 在put操作之前,如果已經(jīng)有該鍵值,會先觸發(fā)removalListener移除監(jiān)聽器,再添加
  • 配置了expireAfterAccess和expireAfterWrite,但在指定時間后沒有被移除。
  • 刪除策略邏輯:
    CacheBuilder構(gòu)建的緩存不會在特定時間自動執(zhí)行清理和回收工作,也不會在某個緩存項過期后馬上清理,它不會啟動一個線程來進行緩存維護,因為首先線程相對較重,其次某些環(huán)境限制線程的創(chuàng)建。

它會在寫操作時順帶做少量的維護工作,或者偶爾在讀操作時做。當(dāng)然,也可以創(chuàng)建自己的維護線程,以固定的時間間隔調(diào)用Cache.cleanUp()。

總結(jié)

到此這篇關(guān)于Java設(shè)置Map過期時間的的幾種方法的文章就介紹到這了,更多相關(guān)Java設(shè)置Map過期時間內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 中校驗時間格式的常見方法

    Java 中校驗時間格式的常見方法

    在實際項目開發(fā)中,跟時間參數(shù)打交道是必不可少的,為了保證程序的安全性、健壯性,一般都會對參數(shù)進行校驗,其他類型的參數(shù)校驗很好實現(xiàn),那你知道時間參數(shù)的是怎么校驗的嗎,下面給大家分享Java 中校驗時間格式的方法,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • SpringBoot使用swagger生成api接口文檔的方法詳解

    SpringBoot使用swagger生成api接口文檔的方法詳解

    在之前的文章中,使用mybatis-plus生成了對應(yīng)的包,在此基礎(chǔ)上,我們針對項目的api接口,添加swagger配置和注解,生成swagger接口文檔,需要的可以了解一下
    2022-10-10
  • springboot項目快速搭建的方法步驟

    springboot項目快速搭建的方法步驟

    這篇文章主要介紹了springboot項目快速搭建的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java面向?qū)ο笾甪inal關(guān)鍵字詳細解讀

    Java面向?qū)ο笾甪inal關(guān)鍵字詳細解讀

    這篇文章主要介紹了Java面向?qū)ο笾甪inal關(guān)鍵字詳細解讀,final修飾的屬性又叫常量,一般用 XX_XX_XX來命名,final修飾的屬性在定義時必須賦初始值,并且以后不能再修改,需要的朋友可以參考下
    2024-01-01
  • 利用Java正則表達式校驗郵箱與手機號

    利用Java正則表達式校驗郵箱與手機號

    利用Java正則表達式校驗郵箱與手機號。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10
  • 使用SpringBoot中web項目推薦目錄結(jié)構(gòu)的問題

    使用SpringBoot中web項目推薦目錄結(jié)構(gòu)的問題

    這篇文章主要介紹了SpringBoot中web項目推薦目錄結(jié)構(gòu)的問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • Mybatis 中的sql批量修改方法實現(xiàn)

    Mybatis 中的sql批量修改方法實現(xiàn)

    在項目中遇到需要批量更新的功能,原本想的是在Java中用循環(huán)訪問數(shù)據(jù)庫去更新,但是心里總覺得這樣做會不會太頻繁了,太耗費資源了,效率也很低,查了下mybatis的批量操作,原來確實有<foreach>標簽可以做到,下面通過本文給大家介紹下
    2017-01-01
  • Java數(shù)組擴容的三大小結(jié)

    Java數(shù)組擴容的三大小結(jié)

    當(dāng)數(shù)組需要容納更多元素時,可以通過擴容來增加其容量,本文主要介紹了Java數(shù)組擴容的三大小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Spring Boot構(gòu)建優(yōu)雅的RESTful接口過程詳解

    Spring Boot構(gòu)建優(yōu)雅的RESTful接口過程詳解

    這篇文章主要介紹了spring boot構(gòu)建優(yōu)雅的RESTful接口過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • packages思維及使用Java添加Android平臺特定實現(xiàn)

    packages思維及使用Java添加Android平臺特定實現(xiàn)

    這篇文章主要為大家介紹了packages思維及使用Java添加Android平臺特定實現(xiàn)在Flutter框架里的體現(xiàn)和運用詳解,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12

最新評論