---------今天看了一下缓存的内容,记一下以备后用。(这些内容都是从网上的综合和案例的综合)
首先缓存可分为两大类:文件缓存和内存缓存
文件缓存,故名思义把数据放在磁盘上,不管是xml或别的。 而内存缓存则是放在内存中。
接下来的问题是如何做到让jvm可以尽量少回收这些cache对象呢 ,一般我们的做法是使用静态变量 而且长用存在hashmap中。如代码:
- 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<String> arr = new ArrayList<String>();
- 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<String> 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<String> 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;
- }
- }
- }
- 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;
- }
- }
但感到似乎不妥,每一次web应用重启好像缓存都没有了 ,而且主要感觉好麻烦,所以决定使用配置文件 (但没解决web重启问题)。
首先建立一个配置文件 ehcache.xml 和你建立的log4j配置文件类似。
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="c://myapp//cache"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"/>
<cache name="DEFAULT_CACHE"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300000"
timeToLiveSeconds="600000"
overflowToDisk="true"/>
</ehcache>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<diskStore path="c://myapp//cache"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"/>
<cache name="DEFAULT_CACHE"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300000"
timeToLiveSeconds="600000"
overflowToDisk="true"/>
</ehcache>
在web.xml文件引用spring-ehcache.xml 这个文件有ehcache文件的引用,同时最主要的是引用了写的类 比较方便。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache/ehcache.xml"
p:shared="false"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="cacheManagerFactory"/>
<bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManagerFactory"
p:cacheName="DEFAULT_CACHE">
</bean>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven/>
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache/ehcache.xml"
p:shared="false"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="cacheManagerFactory"/>
<bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
p:cacheManager-ref="cacheManagerFactory"
p:cacheName="DEFAULT_CACHE">
</bean>
</beans>
以上是在开发项目时,对于缓存的处理。
还有一种就是使用第三方开源项目,比如 百度云 服务。
主要代码如下:
package com.baidu.cloudservice.memcache;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baidu.bae.api.factory.BaeFactory;
import com.baidu.bae.api.memcache.BaeCache;
import java.io.IOException;
import java.io.BufferedOutputStream;
import java.util.Map;
import java.util.Collection;
import java.io.PrintWriter;
import com.baidu.cloudservice.conf.Config;
/**
* BaeMemcache示例,使用Memcache服务实现了加锁功能,注意使用该demo必须在管理界面启用cache服务
*/
public class BaeMemcacheLocker extends HttpServlet {
private static final int LOCK_TIMEOUT = 2000;
private String key = "foo";
private int value = 1;
/**Cache配置信息*/
private String cacheid = Config.CACHEID;
private String username= Config.USER;
private String passwd= Config.PWD;
private String addr = Config.CACHEHOST + ":" + Config.CACHEPORT;
private BaeCache memcache = BaeFactory.getBaeCache(cacheid, addr, username, passwd);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
memcache.delete(key);
boolean lock = memcache.add(key, value,LOCK_TIMEOUT);
if(lock == true){
resp.getWriter().println("There is no lock on this key:" + key + ", do whatever you want");
resp.getWriter().println(memcache.incr(key));
resp.getWriter().println("...increment operation finished! Release lock on the key:" + key);
memcache.delete(key);
}
else{
resp.getWriter().println("The key:" + key + " is currently locked, please wait or do something else");
}
} catch (Exception e) {
e.printStackTrace(resp.getWriter());
}
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baidu.bae.api.factory.BaeFactory;
import com.baidu.bae.api.memcache.BaeCache;
import java.io.IOException;
import java.io.BufferedOutputStream;
import java.util.Map;
import java.util.Collection;
import java.io.PrintWriter;
import com.baidu.cloudservice.conf.Config;
/**
* BaeMemcache示例,使用Memcache服务实现了加锁功能,注意使用该demo必须在管理界面启用cache服务
*/
public class BaeMemcacheLocker extends HttpServlet {
private static final int LOCK_TIMEOUT = 2000;
private String key = "foo";
private int value = 1;
/**Cache配置信息*/
private String cacheid = Config.CACHEID;
private String username= Config.USER;
private String passwd= Config.PWD;
private String addr = Config.CACHEHOST + ":" + Config.CACHEPORT;
private BaeCache memcache = BaeFactory.getBaeCache(cacheid, addr, username, passwd);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
memcache.delete(key);
boolean lock = memcache.add(key, value,LOCK_TIMEOUT);
if(lock == true){
resp.getWriter().println("There is no lock on this key:" + key + ", do whatever you want");
resp.getWriter().println(memcache.incr(key));
resp.getWriter().println("...increment operation finished! Release lock on the key:" + key);
memcache.delete(key);
}
else{
resp.getWriter().println("The key:" + key + " is currently locked, please wait or do something else");
}
} catch (Exception e) {
e.printStackTrace(resp.getWriter());
}
}
}
package com.baidu.cloudservice.memcache;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baidu.bae.api.factory.BaeFactory;
import com.baidu.bae.api.memcache.BaeCache;
import java.io.BufferedOutputStream;
import java.util.Map;
import java.util.Collection;
import java.io.PrintWriter;
import com.baidu.cloudservice.conf.Config;
/**
* BaeMemcache示例,通过示例可快速熟悉BaeMemcache服务的使用方法,注意使用该demo必须在管理界面启用cache服务
*/
public class BaeMemcacheBasic extends HttpServlet {
private static final int TIMEOUT = 2000;
private String key = "foo1";
private int value = 1;
private boolean retVal;
private String output="";
/**Cache配置信息*/
private String cacheid = Config.CACHEID;
private String username= Config.USER;
private String passwd= Config.PWD;
private String addr = Config.CACHEHOST + ":" + Config.CACHEPORT;
private BaeCache memcache = BaeFactory.getBaeCache(cacheid, addr, username, passwd);
private String printOpResult(int num, boolean flag){
String retStr = "";
if(flag == true){
retStr = "Time "+ num + ":add key => value success!";
}else{
retStr = "Time " + num + ":add operation failed!";
}
return retStr;
}
private long caculator(boolean isAdd, String key, int offset){
if(isAdd == true){
return memcache.incr(key, offset);
}
return memcache.decr(key, offset);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
/************************Add and Delete Begin*********************/
//清空cache中关于key的值
memcache.delete(key);
//第一次向cache中增加一条key:value,并且永久有效
retVal = memcache.add(key,value);
output = printOpResult(1, retVal);
resp.getWriter().println(output);
//第二次向cache中增加一条key:value,操作会失败,因为key已经存在
retVal = memcache.add(key,value);
output = printOpResult(2, retVal);
resp.getWriter().println(output);
//删除cache中的key
memcache.delete(key);
//第三次向cache中增加一条key:value,并设置失效时间为TIMEOUT
retVal = memcache.add(key,value,TIMEOUT);
output = printOpResult(3, retVal);
resp.getWriter().println(output);
//do somethig else
Thread.sleep(3000);
//第四次向cache中增加一条key:value,成功
retVal = memcache.add(key,value);
output = printOpResult(4, retVal);
resp.getWriter().println(output);
/************************Add and Delete End*********************/
/*******************Set Get and Replace Begin******************/
//向cache中增加一条key:value,并且永久有效
//当key不存在时,功能相当于add()
retVal = memcache.set(key,value);
output = printOpResult(5, retVal);
resp.getWriter().println(output);
//修改已有的key所对应的值
retVal = memcache.set(key,"abc");
resp.getWriter().println("The new value is "+ memcache.get(key));
//删除cache中的key
memcache.delete(key);
//使用replace,当key不存在时,则返回false
retVal = memcache.replace(key, value);
output = printOpResult(6, retVal);
resp.getWriter().println(output);
//当key存在时,功能和set一样
retVal = memcache.add(key,value);
output = printOpResult(7, retVal);
resp.getWriter().println(output);
retVal = memcache.replace(key, "abc");
resp.getWriter().println("The new value is "+ memcache.get(key));
//删除cache中的key
memcache.delete(key);
/*******************Set Get and Replace End******************/
/*****************Increment and Decrement Begin***************/
retVal = memcache.add(key,value);
output = printOpResult(8, retVal);
resp.getWriter().println("Increment: " + caculator(true, key, 2));
resp.getWriter().println("Decrement: " + caculator(false, key, 2));
//删除cache中的key
memcache.delete(key);
/*****************Increment and Decrement End***************/
} catch (Exception e) {
e.printStackTrace(resp.getWriter());
}
}
}
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.baidu.bae.api.factory.BaeFactory;
import com.baidu.bae.api.memcache.BaeCache;
import java.io.BufferedOutputStream;
import java.util.Map;
import java.util.Collection;
import java.io.PrintWriter;
import com.baidu.cloudservice.conf.Config;
/**
* BaeMemcache示例,通过示例可快速熟悉BaeMemcache服务的使用方法,注意使用该demo必须在管理界面启用cache服务
*/
public class BaeMemcacheBasic extends HttpServlet {
private static final int TIMEOUT = 2000;
private String key = "foo1";
private int value = 1;
private boolean retVal;
private String output="";
/**Cache配置信息*/
private String cacheid = Config.CACHEID;
private String username= Config.USER;
private String passwd= Config.PWD;
private String addr = Config.CACHEHOST + ":" + Config.CACHEPORT;
private BaeCache memcache = BaeFactory.getBaeCache(cacheid, addr, username, passwd);
private String printOpResult(int num, boolean flag){
String retStr = "";
if(flag == true){
retStr = "Time "+ num + ":add key => value success!";
}else{
retStr = "Time " + num + ":add operation failed!";
}
return retStr;
}
private long caculator(boolean isAdd, String key, int offset){
if(isAdd == true){
return memcache.incr(key, offset);
}
return memcache.decr(key, offset);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
/************************Add and Delete Begin*********************/
//清空cache中关于key的值
memcache.delete(key);
//第一次向cache中增加一条key:value,并且永久有效
retVal = memcache.add(key,value);
output = printOpResult(1, retVal);
resp.getWriter().println(output);
//第二次向cache中增加一条key:value,操作会失败,因为key已经存在
retVal = memcache.add(key,value);
output = printOpResult(2, retVal);
resp.getWriter().println(output);
//删除cache中的key
memcache.delete(key);
//第三次向cache中增加一条key:value,并设置失效时间为TIMEOUT
retVal = memcache.add(key,value,TIMEOUT);
output = printOpResult(3, retVal);
resp.getWriter().println(output);
//do somethig else
Thread.sleep(3000);
//第四次向cache中增加一条key:value,成功
retVal = memcache.add(key,value);
output = printOpResult(4, retVal);
resp.getWriter().println(output);
/************************Add and Delete End*********************/
/*******************Set Get and Replace Begin******************/
//向cache中增加一条key:value,并且永久有效
//当key不存在时,功能相当于add()
retVal = memcache.set(key,value);
output = printOpResult(5, retVal);
resp.getWriter().println(output);
//修改已有的key所对应的值
retVal = memcache.set(key,"abc");
resp.getWriter().println("The new value is "+ memcache.get(key));
//删除cache中的key
memcache.delete(key);
//使用replace,当key不存在时,则返回false
retVal = memcache.replace(key, value);
output = printOpResult(6, retVal);
resp.getWriter().println(output);
//当key存在时,功能和set一样
retVal = memcache.add(key,value);
output = printOpResult(7, retVal);
resp.getWriter().println(output);
retVal = memcache.replace(key, "abc");
resp.getWriter().println("The new value is "+ memcache.get(key));
//删除cache中的key
memcache.delete(key);
/*******************Set Get and Replace End******************/
/*****************Increment and Decrement Begin***************/
retVal = memcache.add(key,value);
output = printOpResult(8, retVal);
resp.getWriter().println("Increment: " + caculator(true, key, 2));
resp.getWriter().println("Decrement: " + caculator(false, key, 2));
//删除cache中的key
memcache.delete(key);
/*****************Increment and Decrement End***************/
} catch (Exception e) {
e.printStackTrace(resp.getWriter());
}
}
}
以上代码主要是为了启发作用,供参考。。。。。。