缓存研究

首先我们看一下ehcache.xml文件:
//当缓存对象超过 配置的最大值时 缓存到本机的什么路径下!
//默认是本机temp文件夹下,我们还可以临外指定,如:d://
<diskStore path="java.io.tmpdir"/>


//很有必要对这个<defaultCache/>标签进行特殊介绍:具体参考本文后面的“.java”文//件
<defaultCache
        //内存中最大可以存在多少对象,这里是1w.
        maxElementsInMemory="10000"
       
        //缓存的对象是否永久不过期,默认是false!如果为true,那么
        // timeToIdleSeconds和timeToLiveSeconds将失效,即时你配置了也失效!
        eternal="false"
       
        //元素消亡之前,两次访问最大的时间间隔,举个例子:假设对象最迟在10点整消亡,
        //我们配置为120即两分钟,当我们两次访问的时间间隔是3分钟,即时不到10点,它
       //也会被丢弃!当我们将其设置为0时,那么它将会在10点整被丢弃,这个10点有谁
       //来控制的呢? 回答:timeToLiveSeconds!
        timeToIdleSeconds="120"

        //上面说了,timeToLiveSeconds是来限定一个对象被创建到被销毁的最大时间间
         //隔,这就是暗示着对象的销毁还受timeToIdleSeconds限制!
        timeToLiveSeconds="120"
       
        //当缓存数目达到最大值时,是否允许写磁盘!
        overflowToDisk="true"

       //当jvm 再次启动 的时候是否使用磁盘上的数据 默认是false. 当我们打开
        //myeclipse时 它就启动了jvm,是吗?不是!!我们运行main方法时,要使用
        //run   java application  每运行一次 调用一次jvm!使用完 jvm立刻终止进
        //程或者线程。而我们启动tomcate就相当于使用了run   java application!
diskPersistent="false"
       
        //通过上面的属性配置,我们知道对象在过期的时候,会被清除!有谁来清除?
//ehcache会调用一个线程来完成这些清除工作,下面的配置就是说这个线程多长时//间运行一次run方法,默认是120s
        diskExpiryThreadIntervalSeconds="120"
        />
<cache name="sampleCache1"
        maxElementsInMemory="10"
        eternal="false"
        timeToIdleSeconds="20"
        timeToLiveSeconds="20"
        overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="10"
        />
<cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        />

上面的解释的已经非常清楚,然而一旦拿到了具体环境中我们总是很难把握好:
请看下面的代码
public  static void main(String []args) throws CacheException{
        //获得 缓存管理器
CacheManager cacheManager=CacheManager.create();
       

        //只有2个,不是3个吗?不是还有一个默认的嘛?
        String[] cacheNames = cacheManager.getCacheNames();
System.out.println(cacheNames.length);
        for (String cacheName : cacheNames) {
           System.out.println("缓存的名字:" + cacheName);
        }
       
System.out.println(newSimpleDateFormat("yyyy-MM-ddhh:mm:ss").format(new Date()));
        //获得sampleCache1缓存
        Cache cache=cacheManager.getCache("sampleCache1");
      
        //内存中目前的缓存个数
        System.out.println(cache.getMemoryStoreSize());
      
        //磁盘中目前的缓存个数
        System.out.println(cache.getDiskStoreSize());

         //
        System.out.println(cache.getKeys());

        //由key获得element 再由element获得value
        Element e=cache.get("key_1");
        System.out.println(e.getValue());

通过多次测试,我发现以下情况:
1. 过了失效期,无论对象在哪里,在内存也好,在磁盘也好,都会被丢弃!
2. 在失效时间内,连续run application两次:我们发现第一次内存中和磁盘中对象各10个,再次运行,我们发现他们都变为了0!为什么?难道配置的20s没有起作用?回答:20s起作用了,上面我们的解释说了run java application,每运行一次,就相当于jvm执行一次!如果我们启动了容器,当容器启动后,只要容器不关闭,只要所有对象都在失效时间内,内存中的对象和磁盘中的对象肯定还各是10个
3.这种情况不常用,当我们把上面的diskPersistent该为“true”,执行2的操作,我们发现第一次操作的结果是内存中和磁盘中各10个,在失效期内进行第二次运行结果内存中0个,磁盘中20个!
4.过了失效期,是不是所有对象瞬间都被清除了?不是,但是缓存不会被保存太长时间!



缓存哪些东西?从大的方面讲:缓存java对象,缓存页面。但是哪些java对象,哪些页面适合缓存呢?
一言以蔽之:不经常变动的。
如果你的对象一分钟更新n次,你的页面交互性强大到一分钟交互n次(夸大了!嘿嘿,这里只是为了说明问题而已!)那最好不要使用缓存,我们使用缓存的目的是尽量不从低速的io上取数据(有哪些低速io?数据库就是,磁盘就是),尽量不从网络上获取数据(浏览器缓存就是为了解决尽量相同的请求不从网络上获取数据而出现的。这里我们不谈这个)。而交互性非常强的页面,更新的频度非常高的对象,我们一方面要维护缓存开销,临一方面还要高频度的同步数据库(或磁盘或网络另一端的服务器和其他客户端),那不是“得不偿失”吗?而不经常变动的对象和页面,我们虽然也要维护缓存的开销,但是他们需要同步的频度却非常的低!


说起缓存,我不自觉的想到了servlet中的几个对象,比如request,response,session,application等等。。说起他们我又不自觉的想到了hashmap,他们一定程度上都是存着key-value对!

前段时间我一直很迷茫,为什么不直接自定义一个hashmap来实现缓存呢?你可能会说:“小伙子,不要制造重复的轮子嘛”,人家ehcache和servlet现在已经定义好了,你为什么要再定义一个hashmap,来实现ehcache和servlet本身可以实现的功能,再说ehcache和servlet本身又有许多特性供我们使用,而这些特性的实现代码又如此的复杂,你能保证你自定义的hashmap在这方面做的比servlet和ehache更优秀吗? 恩,有道理!
哪我们为什么不适用servletContext来代替ehcache呢?他们本质上没有什么区别啊?
下面引用banq 老师说的几句话:
如果你直接放在servletContext中,就没有容量大小的限制,有多少内存用多少,直至耗光。

而EHcache这些缓存产品就象一个容器,这个容器也是放在ServletContext中,Ehcache按照一些算法,比如经常使用的留着,不用的就扔掉,定时更新,等等,反正帮助你控制有限的内存。

好了,我不知道bang老师说的是否正确的,但我自己又拿不出令自己信服的“道道”来,目前只能崇信老bang了!
老bang说ehcache能定时刷新缓存?真的吗?当时我看到这句话的时候非常的兴奋,因为我以前一直在使用framemaker的定时器和jdk的timer来实现这些功能,如果ehcache能实现定时刷新缓存,哪岂不省去了我们自己配置定时器的工作?但我找遍了所有的资料,求教了许多前辈,他们都说:“老bang说的?拉到把,根本没这回事!”,看来,也许ehcache应该升级版本了!!!

好现在有这样一个需求,我们的新闻首页需要查询20种新闻类型,每种新闻类型10条,而且新闻首页每星期更新一次。
我说一下我的具体想法:
1. 一定要用到的技术是定时器,定时器的使用有两种选择,一种是framemaker的Quertz,一种是jdk的timer,我个人认为使用framemaker更好一点因为他可以进行“点控制”例如每天10点执行操作,而timer只能是“每过3000秒”这样的循环执行!!
2. 临外一种技术,你可以选择使用ehcache,也可以使用servletcontext(其实是使用监听器)。我个人推荐ehcache!

你可能感兴趣的:(jdk,浏览器,servlet,cache,配置管理)