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); } }
作者: lost blog
出处: http://www.cnblogs.com/JAYIT/
关于作者:专注服务器端开发
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接 如有问题, 可邮件(sawyershaw@qq.com)咨询.