java手写多级缓存
程序员文章站
2024-01-24 13:31:16
多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存)、redis缓存(在spring 的 redisTemplate 基础实现) redis缓存实现类 ......
多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:jvm缓存(实现 请查看上一篇:java 手写jvm高性能缓存)、redis缓存(在spring 的 redistemplate 基础实现)
package com.ws.commons.cache; import java.util.function.supplier; import com.ws.commons.tool.threadtool; /** * 多级缓存实现 * * @author 尘无尘 * */ public class multilevelcache { private multilevelcache() { } private static final icache first_leve_lcache = localcache.instance(); private static icache secondcache; private static final string lock_prefix = "muilcache_lock:"; public static synchronized void init(icache secondcache) { if (multilevelcache.secondcache == null) { multilevelcache.secondcache = secondcache; } } public static void put(string key, object value, int timeoutsecond) { first_leve_lcache.put(key, value, timeoutsecond); if (secondcache != null) { secondcache.put(key, value, timeoutsecond); } } /** * 提供数据,并缓存 * * @param key * @param supplier * @return */ @suppresswarnings("unchecked") public static <t> t getforload(string key, supplier<t> supplier) { t data = first_leve_lcache.get(key); if (data == null && secondcache != null) { data = (t) secondcache.get(key); } if (data != null) { return data; } synchronized (threadtool.buildlock(lock_prefix, key)) { data = first_leve_lcache.get(key); if (data == null && secondcache != null) { data = (t) secondcache.get(key); } if (data != null) { return data; } data = supplier.get(); if (secondcache != null) { secondcache.put(key, data); } first_leve_lcache.put(key, data); } return data; } /** * 提供数据,并缓存一定的时间 * * @param key * @param timeoutsecond * @param supplier * @return */ @suppresswarnings("unchecked") public static <t> t getforload(string key, int timeoutsecond, supplier<t> supplier) { t data = first_leve_lcache.get(key); if (data == null && secondcache != null) { data = (t) secondcache.get(key); } if (data != null) { return data; } synchronized (threadtool.buildlock(lock_prefix, key)) { data = first_leve_lcache.get(key); if (data == null && secondcache != null) { data = (t) secondcache.get(key); } if (data != null) { return data; } data = supplier.get(); if (secondcache != null) { secondcache.put(key, data, timeoutsecond); } first_leve_lcache.put(key, data, timeoutsecond); } return data; } @suppresswarnings("unchecked") public static <t> t removeandget(string key) { t data = null; if (secondcache != null) { data = (t) secondcache.removeandget(key); } t data2 = first_leve_lcache.removeandget(key); if (data == null) { data = data2; } return data; } public static void remove(string key) { if (secondcache != null) { secondcache.remove(key); } first_leve_lcache.remove(key); } @suppresswarnings("unchecked") public static <t> t get(string key) { t data = first_leve_lcache.get(key); if (data == null && secondcache != null) { data = (t) secondcache.get(key); } return data; } public static void expire(string key, int timeoutsecond) { first_leve_lcache.expire(key, timeoutsecond); if (secondcache != null) { secondcache.expire(key, timeoutsecond); } } }
redis缓存实现类
package com.walmart.cirular.interfaces.application; import java.util.concurrent.timeunit; import org.springframework.beans.factory.annotation.autowired; import org.springframework.data.redis.core.redistemplate; import org.springframework.stereotype.component; import com.ws.commons.cache.icache; /** * redis 缓存实现类 * * @author 尘无尘 * */ @component public class redisicacheimpl implements icache { @autowired(required = false) private redistemplate<string, object> redistemplate; @override public void put(string key, object value) { redistemplate.opsforvalue().set(key, value); } @override public void put(string key, object value, int timeoutsecond) { redistemplate.opsforvalue().set(key, value, (long) timeoutsecond, timeunit.seconds); } @suppresswarnings("unchecked") @override public <t> t get(string key) { t t = (t) redistemplate.opsforvalue().get(key); redistemplate.delete(key); return t; } @override public void remove(string key) { redistemplate.delete(key); } @suppresswarnings("unchecked") @override public <t> t removeandget(string key) { object obj = get(key); redistemplate.delete(key); return (t) obj; } @override public void rightpush(string key, object value, int timeoutsecond) { redistemplate.opsforlist().rightpush(key, value); redistemplate.expire(key, timeoutsecond, timeunit.seconds); } @suppresswarnings("unchecked") @override public <t> t rightpop(string key) { return (t) redistemplate.opsforlist().rightpop(key); } @suppresswarnings("unchecked") @override public <t> t leftpop(string key) { return (t) redistemplate.opsforlist().leftpop(key); } @override public void leftpush(string key, object value) { redistemplate.opsforlist().leftpush(key, value); } @override public void rightpush(string key, object value) { redistemplate.opsforlist().rightpush(key, value); } @override public void expire(string key, int timeoutsecond) { redistemplate.expire(key, timeoutsecond, timeunit.seconds); } @override public boolean haskey(string key) { return redistemplate.haskey(key); } @override public boolean putifabsent(string key, object value) { return redistemplate.opsforvalue().setifabsent(key, value); } @override public boolean putifabsent(string key, object value, int timeoutsecond) { boolean flag = putifabsent(key, value); if (flag) { expire(key, timeoutsecond); } return flag; } }