java 缓存的使用

---------今天看了一下缓存的内容,记一下以备后用。(这些内容都是从网上的综合和案例的综合)


首先缓存可分为两大类:文件缓存和内存缓存

文件缓存,故名思义把数据放在磁盘上,不管是xml或别的。 而内存缓存则是放在内存中。

接下来的问题是如何做到让jvm可以尽量少回收这些cache对象呢 ,一般我们的做法是使用静态变量 而且长用存在hashmap中。如代码:
  1. public class CacheManager {   
  2.     private static HashMap cacheMap = new HashMap();   
  3.   
  4.     //单实例构造方法   
  5.     private CacheManager() {   
  6.         super();   
  7.     }   
  8.     //获取布尔值的缓存   
  9.     public static boolean getSimpleFlag(String key){   
  10.         try{   
  11.             return (Boolean) cacheMap.get(key);   
  12.         }catch(NullPointerException e){   
  13.             return false;   
  14.         }   
  15.     }   
  16.     public static long getServerStartdt(String key){   
  17.         try {   
  18.             return (Long)cacheMap.get(key);   
  19.         } catch (Exception ex) {   
  20.             return 0;   
  21.         }   
  22.     }   
  23.     //设置布尔值的缓存   
  24.     public synchronized static boolean setSimpleFlag(String key,boolean flag){   
  25.         if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖   
  26.             return false;   
  27.         }else{   
  28.             cacheMap.put(key, flag);   
  29.             return true;   
  30.         }   
  31.     }   
  32.     public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){   
  33.         if (cacheMap.get(key) == null) {   
  34.             cacheMap.put(key,serverbegrundt);   
  35.             return true;   
  36.         }else{   
  37.             return false;   
  38.         }   
  39.     }   
  40.   
  41.   
  42.     //得到缓存。同步静态方法   
  43.     private synchronized static Cache getCache(String key) {   
  44.         return (Cache) cacheMap.get(key);   
  45.     }   
  46.   
  47.     //判断是否存在一个缓存   
  48.     private synchronized static boolean hasCache(String key) {   
  49.         return cacheMap.containsKey(key);   
  50.     }   
  51.   
  52.     //清除所有缓存   
  53.     public synchronized static void clearAll() {   
  54.         cacheMap.clear();   
  55.     }   
  56.   
  57.     //清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配   
  58.     public synchronized static void clearAll(String type) {   
  59.         Iterator i = cacheMap.entrySet().iterator();   
  60.         String key;   
  61.         ArrayList<String> arr = new ArrayList<String>();   
  62.         try {   
  63.             while (i.hasNext()) {   
  64.                 java.util.Map.Entry entry = (java.util.Map.Entry) i.next();   
  65.                 key = (String) entry.getKey();   
  66.                 if (key.startsWith(type)) { //如果匹配则删除掉   
  67.                     arr.add(key);   
  68.                 }   
  69.             }   
  70.             for (int k = 0; k < arr.size(); k++) {   
  71.                 clearOnly(arr.get(k));   
  72.             }   
  73.         } catch (Exception ex) {   
  74.             ex.printStackTrace();   
  75.         }   
  76.     }   
  77.   
  78.     //清除指定的缓存   
  79.     public synchronized static void clearOnly(String key) {   
  80.         cacheMap.remove(key);   
  81.     }   
  82.   
  83.     //载入缓存   
  84.     public synchronized static void putCache(String key, Cache obj) {   
  85.         cacheMap.put(key, obj);   
  86.     }   
  87.   
  88.     //获取缓存信息   
  89.     public static Cache getCacheInfo(String key) {   
  90.   
  91.         if (hasCache(key)) {   
  92.             Cache cache = getCache(key);   
  93.             if (cacheExpired(cache)) { //调用判断是否终止方法   
  94.                 cache.setExpired(true);   
  95.             }   
  96.             return cache;   
  97.         }else  
  98.             return null;   
  99.     }   
  100.   
  101.     //载入缓存信息   
  102.     public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) {   
  103.         Cache cache = new Cache();   
  104.         cache.setKey(key);   
  105.         cache.setTimeOut(dt + System.currentTimeMillis()); //设置多久后更新缓存   
  106.         cache.setValue(obj);   
  107.         cache.setExpired(expired); //缓存默认载入时,终止状态为FALSE   
  108.         cacheMap.put(key, cache);   
  109.     }   
  110.     //重写载入缓存信息方法   
  111.     public static void putCacheInfo(String key,Cache obj,long dt){   
  112.         Cache cache = new Cache();   
  113.         cache.setKey(key);   
  114.         cache.setTimeOut(dt+System.currentTimeMillis());   
  115.         cache.setValue(obj);   
  116.         cache.setExpired(false);   
  117.         cacheMap.put(key,cache);   
  118.     }   
  119.   
  120.     //判断缓存是否终止   
  121.     public static boolean cacheExpired(Cache cache) {   
  122.         if (null == cache) { //传入的缓存不存在   
  123.             return false;   
  124.         }   
  125.         long nowDt = System.currentTimeMillis(); //系统当前的毫秒数   
  126.         long cacheDt = cache.getTimeOut(); //缓存内的过期毫秒数   
  127.         if (cacheDt <= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE   
  128.             return false;   
  129.         } else { //大于过期时间 即过期   
  130.             return true;   
  131.         }   
  132.     }   
  133.   
  134.     //获取缓存中的大小   
  135.     public static int getCacheSize() {   
  136.         return cacheMap.size();   
  137.     }   
  138.   
  139.     //获取指定的类型的大小   
  140.     public static int getCacheSize(String type) {   
  141.         int k = 0;   
  142.         Iterator i = cacheMap.entrySet().iterator();   
  143.         String key;   
  144.         try {   
  145.             while (i.hasNext()) {   
  146.                 java.util.Map.Entry entry = (java.util.Map.Entry) i.next();   
  147.                 key = (String) entry.getKey();   
  148.                 if (key.indexOf(type) != -1) { //如果匹配则删除掉   
  149.                     k++;   
  150.                 }   
  151.             }   
  152.         } catch (Exception ex) {   
  153.             ex.printStackTrace();   
  154.         }   
  155.   
  156.         return k;   
  157.     }   
  158.   
  159.     //获取缓存对象中的所有键值名称   
  160.     public static ArrayList<String> getCacheAllkey() {   
  161.         ArrayList a = new ArrayList();   
  162.         try {   
  163.             Iterator i = cacheMap.entrySet().iterator();   
  164.             while (i.hasNext()) {   
  165.                 java.util.Map.Entry entry = (java.util.Map.Entry) i.next();   
  166.                 a.add((String) entry.getKey());   
  167.             }   
  168.         } catch (Exception ex) {} finally {   
  169.             return a;   
  170.         }   
  171.     }   
  172.   
  173.     //获取缓存对象中指定类型 的键值名称   
  174.     public static ArrayList<String> getCacheListkey(String type) {   
  175.         ArrayList a = new ArrayList();   
  176.         String key;   
  177.         try {   
  178.             Iterator i = cacheMap.entrySet().iterator();   
  179.             while (i.hasNext()) {   
  180.                 java.util.Map.Entry entry = (java.util.Map.Entry) i.next();   
  181.                 key = (String) entry.getKey();   
  182.                 if (key.indexOf(type) != -1) {   
  183.                     a.add(key);   
  184.                 }   
  185.             }   
  186.         } catch (Exception ex) {} finally {   
  187.             return a;   
  188.         }   
  189.     }   
  190.   
  191. }   
  192.   



  1. public class Cache {   
  2.         private String key;//缓存ID   
  3.         private Object value;//缓存数据   
  4.         private long timeOut;//更新时间   
  5.         private boolean expired; //是否终止   
  6.         public Cache() {   
  7.                 super();   
  8.         }   
  9.   
  10.         public Cache(String key, Object value, long timeOut, boolean expired) {   
  11.                 this.key = key;   
  12.                 this.value = value;   
  13.                 this.timeOut = timeOut;   
  14.                 this.expired = expired;   
  15.         }   
  16.   
  17.         public String getKey() {   
  18.                 return key;   
  19.         }   
  20.   
  21.         public long getTimeOut() {   
  22.                 return timeOut;   
  23.         }   
  24.   
  25.         public Object getValue() {   
  26.                 return value;   
  27.         }   
  28.   
  29.         public void setKey(String string) {   
  30.                 key = string;   
  31.         }   
  32.   
  33.         public void setTimeOut(long l) {   
  34.                 timeOut = l;   
  35.         }   
  36.   
  37.         public void setValue(Object object) {   
  38.                 value = object;   
  39.         }   
  40.   
  41.         public boolean isExpired() {   
  42.                 return expired;   
  43.         }   
  44.   
  45.         public void setExpired(boolean b) {   
  46.                 expired = b;   
  47.         }   


但感到似乎不妥,每一次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>

在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>
以上是在开发项目时,对于缓存的处理。



还有一种就是使用第三方开源项目,比如 百度云 服务。
主要代码如下:
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());
}
}


}

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());
}
}


}


以上代码主要是为了启发作用,供参考。。。。。。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值