美文网首页
写一个java缓存池

写一个java缓存池

作者: 南京确善能 | 来源:发表于2018-06-27 16:04 被阅读0次

    公司项目个人身份票据验证不唯一,原想用cookie解决,但是移动端没办法存储cookie,然后自己写了一个缓存,不多BB,直接上代码。

    /**
     * 
     * @author 黑暗料理界扛把子
     *
     * @Description 缓存实体类  这里自己随意定义成员变量
     */
    public class Cache implements Comparable<Cache>{
        
        private String key;//缓存ID
        private String ip;//ip
        private String ticket;//票据
        private long timeOut;//过期时间
        
        public Cache() {
            super();
        }
        
        public String getKey() {
            return key;
        }
    
        public long getTimeOut() {
            return timeOut;
        }
    
        public Cache(String key, String ip, String ticket, long timeOut) {
            super();
            this.key = key;
            this.ip = ip;
            this.ticket = ticket;
            this.timeOut = timeOut;
        }
    
        public String getIp() {
            return ip;
        }
    
        public void setIp(String ip) {
            this.ip = ip;
        }
    
        public String getTicket() {
            return ticket;
        }
    
        public void setTicket(String ticket) {
            this.ticket = ticket;
        }
    
        public void setKey(String string) {
            key = string;
        }
    
        public void setTimeOut(long l) {
            timeOut = l;
        }
    
    
        @Override
        public int compareTo(Cache o) {
             long r = this.timeOut - o.timeOut;  
             if (r > 0) {  
                 return 1;  
             }  
             if (r < 0) {  
                 return -1;  
             }  
             return 0;  
        }
    
    }
    
    
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Iterator;
    import java.util.PriorityQueue;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.ScheduledThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    import org.apache.log4j.Logger;
    /**
     * 
     * @author 黑暗料理界扛把子
     *
     * @Description 缓存实现类
     */
    @SuppressWarnings("all")
    public class CacheManager {
        
        private static ScheduledExecutorService swapExpiredPool   = new ScheduledThreadPoolExecutor(10);  
        private  ConcurrentHashMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
        private  PriorityQueue<Cache> expireQueue = new PriorityQueue<>(1024);  
        private  Lock lock = new ReentrantLock();
        private static final  CacheManager cm=new CacheManager();
        
        Logger logger=Logger.getLogger(CacheManager.class);
       
        private CacheManager() {
            swapExpiredPool.scheduleWithFixedDelay(new TimeOutCacheTask(), 5, 5, TimeUnit.SECONDS); 
        }
        
        public static CacheManager cm() {    
            return cm;
        }
       
        //获取缓存
        public Cache getCache(String key){
            return cacheMap.get(key);
        }
        
        //设置缓存
        public void putCache(String key,Cache cache){
            lock.lock();  
            try {
                if (hasCache(key)) {
                    expireQueue.remove(cache);
                }
                expireQueue.add(cache);
                cacheMap.put(key, cache);
            }finally {
                 lock.unlock();  
            }
        }
      
        //判断是否存在一个缓存
        private boolean hasCache(String key) {
            return cacheMap.containsKey(key);
        }
      
        //清除所有缓存
        public void clearAll() {
            lock.lock();  
            try {
                cacheMap.clear();
                expireQueue.clear();
            } finally {
                lock.unlock();  
            }
        }
        
        //清除指定的缓存
        public void removeCache(String key) {
            lock.lock();
            try {
                if (hasCache(key)) {
                    cacheMap.remove(key);
                    expireQueue.remove(getCache(key));
                }
            } finally {
                lock.unlock();  
            }
        }
        
        //获取缓存中的大小
        public int getCacheSize() {
            return cacheMap.size();
        }
        
        //重写载入缓存信息方法
        public void setCache(String key,String ip,String ticket){
            Cache cache = new Cache();
            cache.setKey(key);
            cache.setTimeOut(getTimeInMillis());
            cache.setIp(ip);
            cache.setTicket(ticket);
            putCache(key,cache);
        }
      
        //获取缓存对象中的所有键值名称
        public ArrayList getCaches() {
            ArrayList cacheList = new ArrayList();
            try {
                Iterator i = cacheMap.entrySet().iterator();
                while (i.hasNext()) {
                    java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
                    cacheList.add((String) entry.getKey());
                }
            } catch (Exception ex) {} finally {
                return cacheList;
            }
        }
        
       //过期时间设置为10天后
        private long getTimeInMillis(){
            Calendar c = Calendar.getInstance();
            c.set(Calendar.DATE,c.get(Calendar.DATE)+10);
            return c.getTimeInMillis();
        }
        
        //删除已经过期的数据 
        private class TimeOutCacheTask implements Runnable {    
            @Override  
            public void run() {  
                long now = System.currentTimeMillis();  
                while (true) {  
                    lock.lock();  
                    try {  
                        Cache chche = expireQueue.peek();  
                        //没有数据了,或者数据都是没有过期的了  
                        if (chche == null || chche.getTimeOut() > now) {  
                            return;  
                        }  
                        cacheMap.remove(chche.getKey());  
                        expireQueue.poll(); //移除并返回头部元素
                    } finally {  
                        lock.unlock();  
                    }  
                }  
            }  
        } 
    }
    
    

    采用了单例模式,缓存操作都加了锁,代码通俗易懂,就不多BB了。

    相关文章

      网友评论

          本文标题:写一个java缓存池

          本文链接:https://www.haomeiwen.com/subject/ywzbyftx.html