zoukankan      html  css  js  c++  java
  • 读取缓存模拟----FIFO

    本例是模拟缓存的存储和读取。

    存储:使用一个Map来存放,key是文件名,值为缓存对象

    读取:返回相应的key对应的缓存。(如果缓存被修改,就重新加载缓存,再从缓存Map中读取相应缓存)

    测试类:每2秒去获取一次缓存日期,如果文件更新了,则会返回新的缓存日期

    ReloadHandler :
    /** 
     * 重新加载接口 
     * 
     */  
    public interface ReloadHandler {  
        /** 
         * 分析文件 
         * @return 要缓存的内容 
         */  
        Object processNewCache() throws Exception;  
    }  

     

    FileCache :
    /**
     * <pre>
     * final 外部对象操作时:  
     * 通过文件名 -- 在map中找到对应 -- 判断是否修改 --否 -- 返回缓存对象 
     *                  |  
     *                  是 
     *                  | 
     *          调用reload,根据传入的handler进行reload,更新缓存对象,更新操作时间
     * </pre>
     * 
     */
    public class FileCache {
        /** 缓存map */
        private static Map<String, CacheElement> cacheMap = new HashMap<String, CacheElement>();
        private static FileCache fileCache;
        private static final int MAX_SIZE = 20;
        private Queue<String> fileQueue = new LinkedList<String>();
    
        /**
         * 单例,多线程一样自信
         * 
         * @return fileCache单例
         */
        public static FileCache getInstance() {
            if (null == fileCache) {
                fileCache = new FileCache();
            }
            return fileCache;
        }
    
        /**
         * 获取缓存对象 获取缓存,如果文件被修改,则重新加载最近配置,内存中超过20个文件缓存,会自动清理
         * 
         * @param fileName
         * @return
         * @throws Exception
         */
        public Object getCache(String fileName, ReloadHandler handler) throws Exception {
            fileName = fileName.trim();
            if (isModified(fileName)) {
                reLoad(fileName, handler);
            }
            return cacheMap.get(fileName).getCache();
        }
    
        /**
         * 重新加载
         * 
         * @param fileName
         * @param handler
         * @throws Exception
         */
        private void reLoad(String fileName, ReloadHandler handler) throws Exception {
            CacheElement ele = cacheMap.get(fileName);
            if (null == ele) {
                // 文件没有加载过
                ele = new CacheElement();
                // 设置File对象
                ele.setFile(new File(fileName));
                cacheMap.put(fileName, ele);
                // 添加新的缓存,记录到队列中
                if (!fileQueue.contains(fileName)) {
                    // 如果队列中没记录这个,则试图添加并进行清理
                    cacheClean();
                    fileQueue.add(fileName);
                }
            }
            // 更新缓存
            ele.setCache(handler.processNewCache());
            // 更新修改时间
            ele.setLastEditTime(ele.getFile().lastModified());
    
        }
    
        /**
         * 判断是否已经修改
         * 
         * @param fileName
         * @return
         */
        private boolean isModified(String fileName) {
    
            CacheElement cacheElement = cacheMap.get(fileName);
            if (null == cacheElement) {
                // 配置文件没有被加载过
                return true;
            }
            if (cacheElement.getFile().lastModified() != cacheElement.getLastEditTime()) {
                // 被修改
                return true;
            }
            // 没有变化
            return false;
        }
    
        /**
         * FIFO 清理缓存,
         */
        private void cacheClean() {
            // 缓存超过限制之后,进行清理
            if (fileQueue.size() >= MAX_SIZE) {
                String fileName = fileQueue.poll();
                cacheMap.put(fileName, null);
                cacheMap.remove(fileName);
            }
        }
    
        // 私有构造
        private FileCache() {
        }
    
        /**
         * 缓存元素
         * 
         */
        class CacheElement {
    
            public long lastEditTime;
            public File file;
            public Object cache;
    
            public long getLastEditTime() {
    
                return lastEditTime;
            }
    
            public void setLastEditTime(long lastEditTime) {
    
                this.lastEditTime = lastEditTime;
            }
    
            public File getFile() {
                return file;
            }
    
            public void setFile(File file) {
                this.file = file;
            }
    
            public Object getCache() {
                return cache;
            }
    
            public void setCache(Object cache) {
                this.cache = cache;
            }
    
        }
    }

    测试类:

    /**
     * 每2秒去获取一次缓存日期,如果文件更新了,则会返回新的缓存日期
     */
    public class CacheTest {
    
        @Test
        public void getFileContent() {
    
            int count = 10;
            while (count-- > 0) {
                try {
                    getCache();
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void getCache() throws Exception {
    
            Date date = (Date) FileCache.getInstance().getCache("d:/1.txt", new ReloadHandler() {
                @Override
                public Object processNewCache() {
                    System.out.print("find change  ");
                    return new Date();
                }
            });
            System.out.println("cacheData:" + date);
        }
    }

    测试方法:

    在D盘新建一个1.txt,启动测试类,在程序运行中去更改1.txt中的内容,将得到如下结果:

    find change cacheData:Thu Dec 25 15:15:12 CST 2014
    cacheData:Thu Dec 25 15:15:12 CST 2014
    cacheData:Thu Dec 25 15:15:12 CST 2014
    cacheData:Thu Dec 25 15:15:12 CST 2014
    find change cacheData:Thu Dec 25 15:15:20 CST 2014
    cacheData:Thu Dec 25 15:15:20 CST 2014
    cacheData:Thu Dec 25 15:15:20 CST 2014
    cacheData:Thu Dec 25 15:15:20 CST 2014
    cacheData:Thu Dec 25 15:15:20 CST 2014
    cacheData:Thu Dec 25 15:15:20 CST 2014

    <转:http://qihigh-hotmail-com.iteye.com/blog/1329702>

  • 相关阅读:
    【原创】【Android New Features】—— 关于ADT 17的BuildConfig.DEBUG
    《jQuery、jQuery UI及jQuery Mobile技巧与示例》勘误收集
    《jQuery UI开发指南》勘误收集
    获取输入框中选中文本相对于页面的偏移
    html标签对应的英文原文
    CSS选择器解析
    Input File 表单上传按钮美化
    常用CSS代码片断
    web前端开发框架搜集
    Fiddler
  • 原文地址:https://www.cnblogs.com/kevin-yuan/p/4184981.html
Copyright © 2011-2022 走看看