Java中本地緩存的4種實(shí)現(xiàn)方式總結(jié)
前言
在Java開發(fā)中,緩存技術(shù)是提高應(yīng)用性能的關(guān)鍵手段之一。
今天,我們來聊聊Java中的四種主流本地緩存技術(shù),并通過實(shí)例代碼幫助大家更好地理解和應(yīng)用這些技術(shù)。
一、基礎(chǔ)緩存實(shí)現(xiàn)
首先,我們從最基礎(chǔ)的緩存實(shí)現(xiàn)講起。
一個簡單的緩存系統(tǒng)通常包括緩存實(shí)體類、添加、刪除、查詢和清除緩存的功能。
1. 緩存實(shí)體類
緩存實(shí)體類用于存儲緩存的鍵值對以及過期時間。
代碼如下:。
public class CacheEntity { private String cacheKey; private Object cacheValue; private long expireTime; // 過期時間戳 // 構(gòu)造方法、getter和setter省略 }
2. 緩存工具類
接下來,我們實(shí)現(xiàn)一個緩存工具類,使用ConcurrentHashMap
作為存儲結(jié)構(gòu),并通過定時任務(wù)清除過期數(shù)據(jù)。
import java.util.concurrent.*; import java.util.Map; publicclassCacheUtil { privatefinalstatic Map<String, CacheEntity> CACHE_MAP = newConcurrentHashMap<>(); privatestaticScheduledExecutorServiceexecutorService= Executors.newSingleThreadScheduledExecutor(); static { executorService.scheduleAtFixedRate(() -> { longcurrentTime= System.currentTimeMillis(); CACHE_MAP.values().removeIf(entity -> entity.getExpireTime() < currentTime); }, 0, 500, TimeUnit.MILLISECONDS); } publicstaticvoidput(String key, Object value, long expireTimeInSeconds) { longexpireTime= System.currentTimeMillis() + expireTimeInSeconds * 1000; CACHE_MAP.put(key, newCacheEntity(key, value, expireTime)); } publicstatic Object get(String key) { CacheEntityentity= CACHE_MAP.get(key); if (entity == null || entity.getExpireTime() < System.currentTimeMillis()) { CACHE_MAP.remove(key); returnnull; } return entity.getCacheValue(); } publicstaticvoiddelete(String key) { CACHE_MAP.remove(key); } publicstaticvoidclear() { CACHE_MAP.clear(); } }
測試代碼:
public class Test { public static void main(String[] args) throws InterruptedException { CacheUtil.put("name", "zzc", 10L); System.out.println("第一次查詢結(jié)果:" + CacheUtil.get("name")); Thread.sleep(2000L); System.out.println("第二次查詢結(jié)果:" + CacheUtil.get("name")); } }
二、Guava LoadingCache
Guava是Google提供的一個Java基礎(chǔ)庫,其中的LoadingCache是一個強(qiáng)大的緩存工具。
1. 使用示例
import com.google.common.cache.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; publicclassTest { publicstaticvoidmain(String[] args)throws ExecutionException { LoadingCache<String, String> cache = CacheBuilder.newBuilder() .concurrencyLevel(8) .expireAfterWrite(10, TimeUnit.SECONDS) .build(newCacheLoader<String, String>() { @Override public String load(String key)throws Exception { return"default_value"; } }); cache.put("name", "zzc"); StringnameValue= cache.get("name"); StringageValue= cache.get("age", () -> "default_age"); StringsexValue= cache.get("sex", () -> "key 不存在"); System.out.println("nameValue: " + nameValue); System.out.println("ageValue: " + ageValue); System.out.println("sexValue: " + sexValue); } }
在上面的代碼中,當(dāng)調(diào)用cache.get(key)
方法時,如果緩存中不存在對應(yīng)的key,則會通過CacheLoader
的load
方法加載默認(rèn)值。
三、SpringBoot整合Caffeine
Caffeine是一個高性能的Java緩存庫,SpringBoot提供了與Caffeine的無縫整合。
1. 開啟緩存功能
在啟動類上添加@EnableCaching
注解。
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @EnableCaching @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
2. 配置緩存管理器
import com.github.benmanes.caffeine.cache.Caffeine; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.TimeUnit; @Configuration @EnableCaching publicclassCacheConfig { @Bean("caffeineCacheManager") public CacheManager cacheManager() { CaffeineCacheManagercacheManager=newCaffeineCacheManager("userCache"); cacheManager.getCache("userCache").getConfig().setCaffeine(caffeineCacheBuilder()); return cacheManager; } Caffeine<Object, Object> caffeineCacheBuilder() { return Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.SECONDS) .maximumSize(100); } }
3. 使用緩存注解
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service publicclassUserService { // 模擬數(shù)據(jù)庫操作 private Map<Integer, User> userMap = newHashMap<>(); @Cacheable(value = "userCache", key = "#id") public User getUserById(Integer id) { // 假設(shè)從數(shù)據(jù)庫獲取用戶數(shù)據(jù) Useruser=newUser(); user.setId(id); user.setName("User" + id); userMap.put(id, user); return user; } @CacheEvict(value = "userCache", key = "#id") publicvoiddeleteUserById(Integer id) { userMap.remove(id); } }
四、JetCache——阿里巴巴的分布式緩存框架
JetCache是阿里巴巴開源的一款基于Spring和Redis的分布式緩存框架,提供了強(qiáng)大的緩存抽象和注解支持。
1. 引入依賴
在pom.xml
中添加JetCache依賴。
<dependency> <groupId>com.alicp.jetcache</groupId> <artifactId>jetcache-starter-redis</artifactId> <version>最新版本號</version> </dependency>
2. 配置JetCache
在application.yml
中配置JetCache。
jetcache: stat:enable# 開啟統(tǒng)計(jì) remote: default: type:redis keyConvertor:fastjson# 序列化方式 valueEncoder:java valueDecoder:java poolConfig: minIdle:5 maxIdle:20 maxTotal:50 host:localhost port: 6379
3. 使用JetCache注解
import com.alicp.jetcache.anno.CacheType; import com.alicp.jetcache.anno.Cached; import com.alicp.jetcache.anno.CacheUpdate; import com.alicp.jetcache.anno.CacheInvalidate; import org.springframework.stereotype.Service; @Service publicclassUserService { @Cached(name = "userCache", key = "#id", cacheType = CacheType.BOTH) public String getUser(int id) { return"用戶:" + id; } @CacheUpdate(name = "userCache", key = "#id", value = "#user") publicvoidupdateUser(int id, String user) { System.out.println("更新用戶:" + user); } @CacheInvalidate(name = "userCache", key = "#id") publicvoiddeleteUser(int id) { System.out.println("刪除用戶:" + id); } }
JetCache支持本地緩存和遠(yuǎn)程緩存的組合,非常適合分布式系統(tǒng)。
總結(jié)
今天我們一起探索了Java本地緩存的多種實(shí)現(xiàn)方式,從手寫緩存到Guava Cache、Caffeine、Ehcache和JetCache。每種方式都有自己的特點(diǎn)和適用場景。
到此這篇關(guān)于Java中本地緩存的4種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)Java本地緩存實(shí)現(xiàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Data?Elasticsearch?5.x實(shí)現(xiàn)單詞糾錯和自動補(bǔ)全
這篇文章主要為大家介紹了Spring?Data?Elasticsearch?5.x實(shí)現(xiàn)單詞糾錯和自動補(bǔ)全示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08利用spring-boot-maven-plugin插件打包SpringBoot應(yīng)用方式
spring-boot-maven-plugin插件可以將SpringBoot應(yīng)用打成帶依賴的jar包,該包中不僅包含應(yīng)用自身的代碼,還包含了pom.xml中配置的依賴,修改pom.xml打包后,生成的jar包就包含了項(xiàng)目依賴,生成的jar包位于項(xiàng)目的target文件夾下2025-02-02解決Springboot @WebFilter攔截器未生效問題
這篇文章主要介紹了解決Springboot @WebFilter攔截器未生效問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10Java8新特性之Base64詳解_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Java8新特性之Base64的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06