Java 中常用缓存Cache机制的实现

时间:2023-03-09 21:10:30
Java 中常用缓存Cache机制的实现

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

Java 中常用缓存Cache机制的实现

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

缓存主要可分为二大类:

一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;

二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.

代码如下:

package lhm.hcy.guge.frameset.cache; 

import java.util.*; 

 //Description: 管理缓存 

 //可扩展的功能:当chche到内存溢出时必须清除掉最早期的一些缓存对象,这就要求对每个缓存对象保存创建时间 

public class CacheManager {
private static HashMap cacheMap = new HashMap(); //单实例构造方法
private CacheManager() {
super();
}
//获取布尔值的缓存
public static boolean getSimpleFlag(String key){
try{
return (Boolean) cacheMap.get(key);
}catch(NullPointerException e){
return false;
}
}
public static long getServerStartdt(String key){
try {
return (Long)cacheMap.get(key);
} catch (Exception ex) {
return 0;
}
}
//设置布尔值的缓存
public synchronized static boolean setSimpleFlag(String key,boolean flag){
if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖
return false;
}else{
cacheMap.put(key, flag);
return true;
}
}
public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){
if (cacheMap.get(key) == null) {
cacheMap.put(key,serverbegrundt);
return true;
}else{
return false;
}
} //得到缓存。同步静态方法
private synchronized static Cache getCache(String key) {
return (Cache) cacheMap.get(key);
} //判断是否存在一个缓存
private synchronized static boolean hasCache(String key) {
return cacheMap.containsKey(key);
} //清除所有缓存
public synchronized static void clearAll() {
cacheMap.clear();
} //清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配
public synchronized static void clearAll(String type) {
Iterator i = cacheMap.entrySet().iterator();
String key;
ArrayList arr = new ArrayList();
try {
while (i.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
key = (String) entry.getKey();
if (key.startsWith(type)) { //如果匹配则删除掉
arr.add(key);
}
}
for (int k = 0; k < arr.size(); k++) {
clearOnly(arr.get(k));
}
} catch (Exception ex) {
ex.printStackTrace();
}
} //清除指定的缓存
public synchronized static void clearOnly(String key) {
cacheMap.remove(key);
} //载入缓存
public synchronized static void putCache(String key, Cache obj) {
cacheMap.put(key, obj);
} //获取缓存信息
public static Cache getCacheInfo(String key) { if (hasCache(key)) {
Cache cache = getCache(key);
if (cacheExpired(cache)) { //调用判断是否终止方法
cache.setExpired(true);
}
return cache;
}else
return null;
} //载入缓存信息
public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) {
Cache cache = new Cache();
cache.setKey(key);
cache.setTimeOut(dt + System.currentTimeMillis()); //设置多久后更新缓存
cache.setValue(obj);
cache.setExpired(expired); //缓存默认载入时,终止状态为FALSE
cacheMap.put(key, cache);
}
//重写载入缓存信息方法
public static void putCacheInfo(String key,Cache obj,long dt){
Cache cache = new Cache();
cache.setKey(key);
cache.setTimeOut(dt+System.currentTimeMillis());
cache.setValue(obj);
cache.setExpired(false);
cacheMap.put(key,cache);
} //判断缓存是否终止
public static boolean cacheExpired(Cache cache) {
if (null == cache) { //传入的缓存不存在
return false;
}
long nowDt = System.currentTimeMillis(); //系统当前的毫秒数
long cacheDt = cache.getTimeOut(); //缓存内的过期毫秒数
if (cacheDt <= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE
return false;
} else { //大于过期时间 即过期
return true;
}
} //获取缓存中的大小
public static int getCacheSize() {
return cacheMap.size();
} //获取指定的类型的大小
public static int getCacheSize(String type) {
int k = 0;
Iterator i = cacheMap.entrySet().iterator();
String key;
try {
while (i.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
key = (String) entry.getKey();
if (key.indexOf(type) != -1) { //如果匹配则删除掉
k++;
}
}
} catch (Exception ex) {
ex.printStackTrace();
} return k;
} //获取缓存对象中的所有键值名称
public static ArrayList getCacheAllkey() {
ArrayList a = new ArrayList();
try {
Iterator i = cacheMap.entrySet().iterator();
while (i.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
a.add((String) entry.getKey());
}
} catch (Exception ex) {} finally {
return a;
}
} //获取缓存对象中指定类型 的键值名称
public static ArrayList getCacheListkey(String type) {
ArrayList a = new ArrayList();
String key;
try {
Iterator i = cacheMap.entrySet().iterator();
while (i.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
key = (String) entry.getKey();
if (key.indexOf(type) != -1) {
a.add(key);
}
}
} catch (Exception ex) {} finally {
return a;
}
} } package lhm.hcy.guge.frameset.cache; public class Cache {
private String key;//缓存ID
private Object value;//缓存数据
private long timeOut;//更新时间
private boolean expired; //是否终止
public Cache() {
super();
} public Cache(String key, Object value, long timeOut, boolean expired) {
this.key = key;
this.value = value;
this.timeOut = timeOut;
this.expired = expired;
} public String getKey() {
return key;
} public long getTimeOut() {
return timeOut;
} public Object getValue() {
return value;
} public void setKey(String string) {
key = string;
} public void setTimeOut(long l) {
timeOut = l;
} public void setValue(Object object) {
value = object;
} public boolean isExpired() {
return expired;
} public void setExpired(boolean b) {
expired = b;
}
} //测试类,
class Test {
public static void main(String[] args) {
System.out.println(CacheManager.getSimpleFlag("alksd"));
// CacheManager.putCache("abc", new Cache());
// CacheManager.putCache("def", new Cache());
// CacheManager.putCache("ccc", new Cache());
// CacheManager.clearOnly("");
// Cache c = new Cache();
// for (int i = 0; i < 10; i++) {
// CacheManager.putCache("" + i, c);
// }
// CacheManager.putCache("aaaaaaaa", c);
// CacheManager.putCache("abchcy;alskd", c);
// CacheManager.putCache("cccccccc", c);
// CacheManager.putCache("abcoqiwhcy", c);
// System.out.println("删除前的大小:"+CacheManager.getCacheSize());
// CacheManager.getCacheAllkey();
// CacheManager.clearAll("aaaa");
// System.out.println("删除后的大小:"+CacheManager.getCacheSize());
// CacheManager.getCacheAllkey(); }
}

spring中的redis service实现

package com.eshore.ismp.cache.redis;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; @Service
public class RedisService { private static String redisCode = "utf-8"; @Autowired
private RedisTemplate<String, String> redisTemplate; /**
* 从指定的列表右边出队,添加到目的列表中
*
* @param srckey
* 源列表
* @param dstkey
*  目的列表
* @return
*/
public String rpoppush(final String srckey, final String dstkey) {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
try {
return new String (connection.rPopLPush(srckey.getBytes(), dstkey.getBytes()), redisCode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
});
}
/**
* 获取指定列表的范围数据
*
* @param key
*  列表名
* @param start
*  开始位置
* @param end
*  结束位置
* @return
*/
public List<String> lrange(final String key, final int start, final int end) {
return redisTemplate.execute(new RedisCallback<List<String>>() {
List<String> result = new ArrayList<String>();
public List<String> doInRedis(RedisConnection connection)
throws DataAccessException {
List<byte[]> bytelist= connection.lRange(key.getBytes(), start, end);
for (byte[] b : bytelist) {
try {
result.add(new String(b, redisCode));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return result;
}
});
}
/**
* 从队列的左边取出一条数据
*
* @param key
*  列表名
* @return
*/
public String lpop(final String key) {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] result = connection.lPop(key.getBytes());
if (result != null) {
try {
return new String (result , redisCode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return "";
}
});
} /**
* 从队列的左边取出一条数据
*
* @param key
*  列表名
* @return
*/
public List<?> lpop(final String key,final int size) {
List<Object> list = redisTemplate.executePipelined(new RedisCallback<List<Object>>() {
public List<Object> doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] keyBytes = key.getBytes();
for(int i =0 ; i< size; i++){
connection.lPop(keyBytes);
}
return null;
}
});
list.removeAll(Collections.singleton(null));
return list;
} /**
* 从列表右边添加数据
*
* @param key
* 列表名
* @param values
* 数据
* @return
*/
public long rpush(final String key, final String... values) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
long result = 0;
for (String v : values) {
result = connection.rPush(key.getBytes(), v.getBytes());
}
return result;
}
});
} /**
* 从列表右边添加数据
*
* @param key
* 列表名
* @param values
* 数据
* @return
*/
public long rpush(final String key, final Collection<String> values) {
return redisTemplate.opsForList().rightPushAll(key, values);
} public int hmset(final String key, final Map<String,String> values) {
try{
redisTemplate.opsForHash().putAll(key, values);
}catch(Exception e){
e.printStackTrace();
return -1;
}
return 0 ;
}
public String hget(final String key, final String field){
Object obj =redisTemplate.opsForHash().get(key, field);
return String.valueOf(obj);
} public List<?> hkeys(final String key){
return redisTemplate.execute(new RedisCallback<List<Object>>(){
List<Object> list = new ArrayList<Object>();
public List<Object> doInRedis(RedisConnection connection)
throws DataAccessException {
Set<byte[]> sets=connection.hKeys(key.getBytes());
if(!sets.isEmpty()){
for(byte[] b : sets){
list.add(redisTemplate.getValueSerializer().deserialize(b).toString());
}
return list;
}
return null;
}
});
} /**
* 删除hash表中field
*/
public void hdel(final String key,final String field){
redisTemplate.opsForHash().delete(key, field);
}
/**
* 从列表右边添加数据,并且设置列表的存活时间
*
* @param key
* 列表名
* @param liveTime
* 存活时间(单位 秒)
* @param values
* 数据
* @return
*/
public long rpush(final String key, final int liveTime, final String... values) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
long result = 0;
for (String v : values) {
connection.rPush(key.getBytes(), v.getBytes());
}
if (liveTime > 0) {
connection.expire(key.getBytes(), liveTime);
}
return result;
}
});
}
/**
* 从队列的右边取出一条数据
*
* @param key
* 列表名
* @return
*/
public String rpop(final String key) {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] result = connection.rPop(key.getBytes());
if(result != null ){
try {
return new String (result, redisCode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return "";
}
});
}
/**
* 把一个值添加到对应列表中
*
* @param key
* 列表名
* @param index
*  添加的位置
* @param value
*  数据
* @return
*/
public String lset(final String key, final long index, final String value) {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
connection.lSet(key.getBytes(), index, value.getBytes());
return "success";
}
});
}
/**
* 把所有数据添加到一个列表中
*
* @param key
* 列表名
* @param values
*  数据
* @return
*/
public long lpush(String key, String... values) {
return this.lpush(key, 0, values);
}
/**
* 把所有数据添加到一个列表中,并且设置列表的存活时间
*
* @param key
* 列表名
* @param values
* 数据
* @param liveTime
* 存活时间--单位(秒)
* @return
*/
public long lpush(final String key,final int liveTime, final String... values) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
long result = 0;
for (String v : values){
result = connection.lPush(key.getBytes(), v.getBytes());
}
if (liveTime > 0) {
connection.expire(key.getBytes(), liveTime);
}
return result;
}
});
}
/**
* 返回列表的长度
*
* @param key
* @return
*/
public long llen(final String key) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.lLen(key.getBytes());
}
});
}
/**
* 删除列表中对应值的元素
*
* @param key
* 列表名
* @param count
* 删除多少个相同的元素
* @param value
* 数据
* @return
*/
public long lrem(final String key, final long count, final String value) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.lRem(key.getBytes(), count, value.getBytes());
}
});
}
/**
* 通过keys批量删除
*
* @param key
*/
public long del(final String... keys) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
long result = 0;
for (String k : keys) {
result = connection.del(k.getBytes());
}
return result;
}
});
} /**
*
* //DESC 删除单个key
* @time: 2016年5月27日 上午9:00:36
* @param key
* @return
* @throws
*/
public long del(final String key){
return redisTemplate.execute(new RedisCallback<Long>(){
@Override
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.del(key.getBytes());
} });
} /**
* 添加key value 并且设置存活时间(byte)
*
* @param key
* @param value
* @param liveTime
*/
public void set(final byte[] key, final byte[] value, final long liveTime) {
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
connection.set(key, value);
if (liveTime > 0) {
connection.expire(key, liveTime);
}
return 1L;
}
}); }
/**
* 添加key value 并且设置存活时间
*
* @param key
* @param value
* @param liveTime
* 单位秒
*/
public void set(String key, String value, long liveTime) {
this.set(key.getBytes(), value.getBytes(), liveTime); }
/**
* 添加key value
*
* @param key
* @param value
*/
public void set(String key, String value) {
this.set(key, value, 0L);
} /**
* 添加key value
*
* @param key
* @param value
*/
public void setMulti(final Map<String,String> map) {
setMulti(map,0L);
} /**
* 添加key value
*
* @param key
* @param value
*/
public void setMulti(final Map<String,String> map,final long liveTime) {
redisTemplate.executePipelined(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
Set<Map.Entry<String, String >> set = map.entrySet();
for (Entry<String, String> entry : set) {
connection.set(entry.getKey().getBytes(), entry.getValue().getBytes());
if (liveTime > 0) {
connection.expire(entry.getKey().getBytes(), liveTime);
}
}
return null;
}
});
}
/**
* 添加key value (字节)(序列化)
*
* @param key
* @param value
*/
public void set(byte[] key, byte[] value) {
this.set(key, value, 0L); }
/**
* 获取redis value (String)
*
* @param key
* @return
*/
public String get(final String key) {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
byte[] result = connection.get(key.getBytes());
if (result != null) {
try {
return new String (result ,redisCode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return "";
}
});
}
/**
* 如果key不存在添加key value 并且设置存活时间(byte),当key已经存在时,就不做任何操作
*
* @param key
* @param value
* @param liveTime
*/
public long setnx(final byte[] key, final byte[] value, final long liveTime) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
long result = 0l;
boolean isSuccess = connection.setNX(key, value);
if (isSuccess) {
if (liveTime > 0) {
connection.expire(key, liveTime);
}
result = 1l;
}
return result;
}
});
}
/**
* 如果key不存在添加key value 并且设置存活时间,当key已经存在时,就不做任何操作
*
* @param key
* @param value
* @param liveTime
* 单位秒
*/
public long setnx(String key, String value, long liveTime) {
return this.setnx(key.getBytes(), value.getBytes(), liveTime); }
/**
* 如果key不存在添加key value,当key已经存在时,就不做任何操作
*
* @param key
* @param value
*/
public long setnx(String key, String value) {
return this.setnx(key, value, 0L);
}
/**
* 如果key不存在添加key value (字节)(序列化),当key已经存在时,就不做任何操作
*
* @param key
* @param value
*/
public long setnx(byte[] key, byte[] value) {
return this.setnx(key, value, 0L); }
/**
* 通过正则匹配keys
*
* @param pattern
* @return
*/
public Set<String> keys(final String pattern) {
return redisTemplate.execute(new RedisCallback<Set<String>>() {
public Set<String> doInRedis(RedisConnection connection)
throws DataAccessException {
Set<String> result = new HashSet<String>();
Set<byte[]> data = connection.keys(pattern.getBytes());
for(byte[] d : data){
try {
result.add(new String(d,redisCode));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return result;
}
});
}
/**
* 检查key是否已经存在
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.exists(key.getBytes());
} });
}
/**
* 清空redis 所有数据
*
* @return
*/
public String flushDB() {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
connection.flushDb();
return "success";
}
});
}
/**
* 查看redis里有多少数据
*/
public long dbSize() {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.dbSize();
}
});
}
/**
* 检查是否连接成功
*
* @return
*/
public String ping() {
return redisTemplate.execute(new RedisCallback<String>() {
public String doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.ping();
}
});
}
/**
* 设置key的生命周期
*
* @param key
* @param seconds
* 单位(秒)
* @return
*/
public boolean expire(final String key, final long seconds) {
return redisTemplate.execute(new RedisCallback<Boolean>() {
public Boolean doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.expire(key.getBytes(), seconds);
}
});
}
/**
* 自增长
*
* @param key
* @param length 增长步长
* @return
*/
public long incr (final String key){
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.incr(key.getBytes());
} });
}
/**
* 自增长
*
* @param key
* @param length 增长步长
* @return
*/
public long incrBy (final String key, final long len){
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.incrBy(key.getBytes(), len);
}
}); }
/**
* 自增长
*
* @param key
* @param length 增长步长
* @return
*/
public double incrBy (final String key, final double len){
return redisTemplate.execute(new RedisCallback<Double>() {
public Double doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.incrBy(key.getBytes(), len);
}
});
} public long eval(final String luaCommand) {
return redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.eval(luaCommand.getBytes(), null,0);
}
});
} }

  

缓存应用:

package com.eshore.ismp.cache.processor;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eshore.ismp.cache.redis.RedisService;
import com.eshore.ismp.common.entity.ResultInfo; /**
*
* //DESC: 管理门户缓存接口
* @author zzx
* @date 2016年5月20日 上午11:50:25
*/
@Service
public class AdminWebProcessor {
private static final Logger logger = Logger.getLogger(AdminWebProcessor.class);
private static final String ADMINWEB_USER = "ADMINWEB_USER_";
private static final Long LIVETIME = 60*30L;
@Autowired
RedisService redisService; public String put(JSONObject param){
Long userId = param.getLong("user_id");
String userInfo = param.getString("user_info");
ResultInfo rs = new ResultInfo();
if(userId==null || StringUtils.isEmpty(userInfo)){
logger.error("参数错误");
rs.setResult_code(2501);
rs.setResult_detail("参数错误");
return JSON.toJSONString(rs);
}
String key = ADMINWEB_USER+userId;
redisService.set(key , userInfo,LIVETIME);
rs.setResult_code(0);
rs.setResult_detail("success");
return JSON.toJSONString(rs);
} public String get(JSONObject param){
Long userId = param.getLong("user_id");
String key = ADMINWEB_USER+userId;
ResultInfo rs = new ResultInfo();
String user = redisService.get(key);
rs.setResult_code(0);
rs.setResult_detail("success");
rs.setResult_data(user);
return JSON.toJSONString(rs);
} public String delete(JSONObject param){
Long userId = param.getLong("user_id");
String key = ADMINWEB_USER+userId;
ResultInfo rs = new ResultInfo();
long isDel = redisService.del(key);
rs.setResult_code(0);
rs.setResult_detail("success");
return JSON.toJSONString(rs);
} }