• ehcache2.8.3入门示例:hello world


    一、pom.xml 依赖项

     1 <dependency>
     2             <groupId>net.sf.ehcache</groupId>
     3             <artifactId>ehcache</artifactId>
     4             <version>2.8.3</version>
     5         </dependency>
     6 
     7         <dependency>
     8             <groupId>org.slf4j</groupId>
     9             <artifactId>slf4j-api</artifactId>
    10             <version>1.7.7</version>
    11         </dependency>
    View Code

    二、ehcache.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 
     3 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
     5     monitoring="autodetect" dynamicConfig="true">
     6 
     7 
     8     <diskStore path="java.io.tmpdir" />
     9 
    10     <defaultCache maxEntriesLocalHeap="10000" eternal="false"
    11         timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
    12         maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
    13         memoryStoreEvictionPolicy="LRU">
    14         <persistence strategy="localTempSwap" />
    15     </defaultCache>
    16 
    17     <cache name="sampleCache1" maxEntriesLocalHeap="10000"
    18         maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="20"
    19         timeToIdleSeconds="300" timeToLiveSeconds="600"
    20         memoryStoreEvictionPolicy="LFU" transactionalMode="off">
    21         <persistence strategy="localTempSwap" />
    22     </cache>
    23 
    24     <cache name="sampleCache2" maxEntriesLocalHeap="1000" eternal="true"
    25         memoryStoreEvictionPolicy="FIFO" />
    26 
    27 </ehcache>
    View Code


    三、示例代码

     1 package cnblogs.ehcache;
     2 
     3 import net.sf.ehcache.Cache;
     4 import net.sf.ehcache.CacheManager;
     5 import net.sf.ehcache.Element;
     6 
     7 public class App {
     8     public static void main(String[] args) throws InterruptedException {
     9         CacheManager manager = CacheManager.create();
    10 
    11         // 取出所有的cacheName
    12         String names[] = manager.getCacheNames();
    13         System.out.println("----all cache names----");
    14         for (int i = 0; i < names.length; i++) {
    15             System.out.println(names[i]);
    16         }
    17 
    18         System.out.println("----------------------");
    19         // 得到一个cache对象
    20         Cache cache1 = manager.getCache(names[0]);
    21 
    22         // 向cache1对象里添加缓存
    23         cache1.put(new Element("key1", "values1"));
    24         Element element = cache1.get("key1");
    25 
    26         // 读取缓存
    27         System.out.println("key1 	= " + element.getObjectValue());
    28 
    29         // 手动创建一个cache(ehcache里必须有defaultCache存在,"test"可以换成任何值)
    30         Cache cache2 = new Cache("test", 1, true, false, 2, 3);
    31         manager.addCache(cache2);
    32 
    33         cache2.put(new Element("jimmy", "菩提树下的杨过"));
    34 
    35         // 故意停1.5秒,以验证是否过期
    36         Thread.sleep(1500);
    37 
    38         Element eleJimmy = cache2.get("jimmy");
    39 
    40         //1.5s < 2s 不会过期
    41         if (eleJimmy != null) {
    42             System.out.println("jimmy 	= " + eleJimmy.getObjectValue());
    43         }
    44 
    45         //再等上0.5s, 总时长:1.5 + 0.5 >= min(2,3),过期
    46         Thread.sleep(500);
    47 
    48         eleJimmy = cache2.get("jimmy");
    49 
    50         if (eleJimmy != null) {
    51             System.out.println("jimmy 	= " + eleJimmy.getObjectValue());
    52         }
    53 
    54         // 取出一个不存在的缓存项
    55         System.out.println("fake 	= " + cache2.get("fake"));
    56 
    57         manager.shutdown();
    58     }
    59 
    60 }
    View Code

    运行结果:

    ----all cache names----
    sampleCache2
    sampleCache1
    ----------------------
    key1     = values1
    jimmy     = 菩提树下的杨过
    fake     = null

    四、关于timeToLiveSeconds、timeToIdleSeconds

    这二个参数直接影响缓存项的过期时间,看文档说明基本上没啥用,直接看net.sf.ehcache.Element源码的片段:

      1 /**
      2      * The amount of time for the element to live, in seconds. 0 indicates unlimited.
      3      */
      4     private volatile int timeToLive = Integer.MIN_VALUE;
      5 
      6     /**
      7      * The amount of time for the element to idle, in seconds. 0 indicates unlimited.
      8      */
      9     private volatile int timeToIdle = Integer.MIN_VALUE;
     10     
     11     
     12     /**
     13      * Sets time to Live
     14      * <P/>
     15      * Value must be a positive integer, 0 means infinite time to live.
     16      * <P/>
     17      * If calling this method with 0 as the parameter, consider using {@link #setEternal(boolean)}
     18      * or make sure you also explicitly call {@link #setTimeToIdle(int)}.
     19      *
     20      * @param timeToLiveSeconds the number of seconds to live
     21      */
     22     public void setTimeToLive(final int timeToLiveSeconds) {
     23         if (timeToLiveSeconds < 0) {
     24             throw new IllegalArgumentException("timeToLive can't be negative");
     25         }
     26         this.cacheDefaultLifespan = false;
     27         this.timeToLive = timeToLiveSeconds;
     28     }
     29 
     30     /**
     31      * Sets time to idle
     32      * <P/>
     33      * Value must be a positive integer, 0 means infinite time to idle.
     34      * <P/>
     35      * If calling this method with 0 as the parameter, consider using {@link #setEternal(boolean)}
     36      * or make sure you also explicitly call {@link #setTimeToLive(int)}.
     37      *
     38      * @param timeToIdleSeconds the number of seconds to idle
     39      */
     40     public void setTimeToIdle(final int timeToIdleSeconds) {
     41         if (timeToIdleSeconds < 0) {
     42             throw new IllegalArgumentException("timeToIdle can't be negative");
     43         }
     44         this.cacheDefaultLifespan = false;
     45         this.timeToIdle = timeToIdleSeconds;
     46     }
     47     
     48     
     49 
     50     /**
     51      * An element is expired if the expiration time as given by {@link #getExpirationTime()} is in the past.
     52      *
     53      * @return true if the Element is expired, otherwise false. If no lifespan has been set for the Element it is
     54      *         considered not able to expire.
     55      * @see #getExpirationTime()
     56      */
     57     public boolean isExpired() {
     58         if (!isLifespanSet() || isEternal()) {
     59             return false;
     60         }
     61 
     62         long now = System.currentTimeMillis();
     63         long expirationTime = getExpirationTime();
     64 
     65         return now > expirationTime;
     66     }
     67     
     68     
     69     /**
     70      * An element is expired if the expiration time as given by {@link #getExpirationTime()} is in the past.
     71      * <p>
     72      * This method in addition propogates the default TTI/TTL values of the supplied cache into this element.
     73      *
     74      * @param config config to take default parameters from
     75      * @return true if the Element is expired, otherwise false. If no lifespan has been set for the Element it is
     76      *         considered not able to expire.
     77      * @see #getExpirationTime()
     78      */
     79     public boolean isExpired(CacheConfiguration config) {
     80         if (cacheDefaultLifespan) {
     81             if (config.isEternal()) {
     82                 timeToIdle = 0;
     83                 timeToLive = 0;
     84             } else {
     85                 timeToIdle = TimeUtil.convertTimeToInt(config.getTimeToIdleSeconds());
     86                 timeToLive = TimeUtil.convertTimeToInt(config.getTimeToLiveSeconds());
     87             }
     88         }
     89         return isExpired();
     90     }
     91 
     92     /**
     93      * Returns the expiration time based on time to live. If this element also has a time to idle setting, the expiry
     94      * time will vary depending on whether the element is accessed.
     95      *
     96      * @return the time to expiration
     97      */
     98     public long getExpirationTime() {
     99         if (!isLifespanSet() || isEternal()) {
    100             return Long.MAX_VALUE;
    101         }
    102 
    103         long expirationTime = 0;
    104         long ttlExpiry = creationTime + TimeUtil.toMillis(getTimeToLive());
    105 
    106         long mostRecentTime = Math.max(creationTime, lastAccessTime);
    107         long ttiExpiry = mostRecentTime + TimeUtil.toMillis(getTimeToIdle());
    108 
    109         if (getTimeToLive() != 0 && (getTimeToIdle() == 0 || lastAccessTime == 0)) {
    110             expirationTime = ttlExpiry;
    111         } else if (getTimeToLive() == 0) {
    112             expirationTime = ttiExpiry;
    113         } else {
    114             expirationTime = Math.min(ttlExpiry, ttiExpiry);
    115         }
    116         return expirationTime;
    117     }
    118 
    119     /**
    120      * @return true if the element is eternal
    121      */
    122     public boolean isEternal() {
    123         return (0 == timeToIdle) && (0 == timeToLive);
    124     }
    125     
    126     
    127     /**
    128      * Sets whether the element is eternal.
    129      *
    130      * @param eternal
    131      */
    132     public void setEternal(final boolean eternal) {
    133         if (eternal) {
    134             this.cacheDefaultLifespan = false;
    135             this.timeToIdle = 0;
    136             this.timeToLive = 0;
    137         } else if (isEternal()) {
    138             this.cacheDefaultLifespan = false;
    139             this.timeToIdle = Integer.MIN_VALUE;
    140             this.timeToLive = Integer.MIN_VALUE;
    141         }
    142     }
    143 
    144     /**
    145      * Whether any combination of eternal, TTL or TTI has been set.
    146      *
    147      * @return true if set.
    148      */
    149     public boolean isLifespanSet() {
    150         return this.timeToIdle != Integer.MIN_VALUE || this.timeToLive != Integer.MIN_VALUE;
    151     }
    152 
    153     /**
    154      * @return the time to live, in seconds
    155      */
    156     public int getTimeToLive() {
    157         if (Integer.MIN_VALUE == timeToLive) {
    158             return 0;
    159         } else {
    160             return timeToLive;
    161         }
    162     }
    163 
    164     /**
    165      * @return the time to idle, in seconds
    166      */
    167     public int getTimeToIdle() {
    168         if (Integer.MIN_VALUE == timeToIdle) {
    169             return 0;
    170         } else {
    171             return timeToIdle;
    172         }
    173     }
    174     
    175     
    176     /**
    177      * Set the default parameters of this element - those from its enclosing cache.
    178      * @param tti TTI in seconds
    179      * @param ttl TTL in seconds
    180      * @param eternal <code>true</code> if the element is eternal.
    181      */
    182     protected void setLifespanDefaults(int tti, int ttl, boolean eternal) {
    183         if (eternal) {
    184             this.timeToIdle = 0;
    185             this.timeToLive = 0;
    186         } else if (isEternal()) {
    187             this.timeToIdle = Integer.MIN_VALUE;
    188             this.timeToLive = Integer.MIN_VALUE;
    189         } else {
    190             timeToIdle = tti;
    191             timeToLive = ttl;
    192         }
    193     }
    View Code

    结论:

    a) timeToIdleSeconds(空闲时间)、timeToLiveSeconds(生存时间)都设置为0时,表示不过期

    b) 如果只有timeToLiveSeconds设置>0的值,则Element的过期时间为 timeToLiveSeconds

    c) 如果只有timeToIdleSeconds设置>0的值,则Element的过期时间为 (上次访问时间+timeToIdleSeconds),说得更通俗点,上次get过了,现在又想get,若二次get的时间间隔>timeToIdleSeconds,则过期(即:最后一次get出来为null)

    d) 如果timeToLiveSeconds、timeToIdleSeconds有>0的值,则最终过期时间为 b),c)规则综合起来,取二者的最小值


    测试1:

     1     @Test
     2     public void testTimeToIdleSeconds() throws InterruptedException {
     3         CacheManager manager = CacheManager.create();
     4 
     5         Cache myCache = new Cache("MyCache", 1, true, false, 0, 0); // Cache上设置为永不过期
     6         manager.addCache(myCache);
     7 
     8         String key = "A";
     9 
    10         System.out.println("-------------------------");
    11         Element elementPut = new Element(key, "Some Value", 2, 0); // timeToIdleSeconds为2秒
    12 
    13         myCache.put(elementPut);// 放入缓存
    14         System.out.println(myCache.get(key));// 取出显示
    15 
    16         Thread.sleep(1500);// 停1.5秒
    17         System.out.println(myCache.get(key));// 再次取出
    18 
    19         Thread.sleep(1500);// 停1.5秒
    20         System.out.println(myCache.get(key));// 虽然总时间已达3秒,但刚刚被访问过了,所以又可以再"活"2秒,仍然有效
    21 
    22         Thread.sleep(2500);// 停2.5秒
    23         System.out.println(myCache.get(key));// 距离上次访问已过2.5s,已经>2s,过期
    24 
    25     }
    View Code

    输出结果

    [ key = A, value=Some Value, version=1, hitCount=1, CreationTime = 1407898361782, LastAccessTime = 1407898361787 ]
    [ key = A, value=Some Value, version=1, hitCount=2, CreationTime = 1407898361782, LastAccessTime = 1407898363287 ]
    [ key = A, value=Some Value, version=1, hitCount=3, CreationTime = 1407898361782, LastAccessTime = 1407898364787 ]
    null

    测试2:

     1     @Test
     2     public void testTimeToLiveSeconds() throws InterruptedException {
     3         CacheManager manager = CacheManager.create();
     4 
     5         Cache myCache = new Cache("MyCache", 1, true, false, 0, 0); // Cache上设置为永不过期
     6         manager.addCache(myCache);
     7 
     8         String key = "A";
     9 
    10         System.out.println("-------------------------");
    11         Element elementPut = new Element(key, "Some Value", 0, 2); // timeToLiveSeconds为2秒
    12 
    13         myCache.put(elementPut);// 放入缓存
    14         System.out.println(myCache.get(key));// 取出显示
    15 
    16         Thread.sleep(1500);// 停1.5秒
    17         System.out.println(myCache.get(key));// 再次取出(1.5s<2s,还"活"着)
    18 
    19         Thread.sleep(1500);// 停1.5秒
    20         System.out.println(myCache.get(key));// 总时间已达3s,>2s,已过期)
    21 
    22     }
    View Code

    输出结果

    [ key = A, value=Some Value, version=1, hitCount=1, CreationTime = 1407898423291, LastAccessTime = 1407898423296 ]
    [ key = A, value=Some Value, version=1, hitCount=2, CreationTime = 1407898423291, LastAccessTime = 1407898424797 ]
    null

    测试3:

     1 @Test
     2     public void testTimeToIdleSecondsAndTimeToLiveSeconds()
     3             throws InterruptedException {
     4         CacheManager manager = CacheManager.create();
     5 
     6         Cache myCache = new Cache("MyCache", 1, true, false, 0, 0); // Cache上设置为永不过期
     7         manager.addCache(myCache);
     8 
     9         String key = "A";
    10 
    11         System.out.println("-------------------------");
    12         Element elementPut = new Element(key, "Some Value", 2, 5); // timeToIdleSeconds为2秒,timeToLiveSeconds为3秒
    13 
    14         myCache.put(elementPut);// 放入缓存
    15         System.out.println(myCache.get(key));// 取出显示
    16 
    17         Thread.sleep(1600);// 停1.6秒
    18         System.out.println(myCache.get(key));// 再次取出(1.6s < min(2 ,5),还"活"着)
    19 
    20         Thread.sleep(1600);// 停1.6秒
    21         System.out.println(myCache.get(key));// 总时间已达3.2s,< min((1.6+2) ,5),还"活"着)
    22         
    23         Thread.sleep(1600);// 停1.6秒
    24         System.out.println(myCache.get(key));// 总时间已达4.8s,< min((3.2+2) ,5),还"活"着)
    25         
    26         Thread.sleep(500);// 停0.5秒
    27         System.out.println(myCache.get(key));// 总时间已达4.8+0.5=5.3s,> min((4.8+2) ,5),过期)
    28 
    29     }
    View Code

    输出结果

    [ key = A, value=Some Value, version=1, hitCount=1, CreationTime = 1407898480892, LastAccessTime = 1407898480897 ]
    [ key = A, value=Some Value, version=1, hitCount=2, CreationTime = 1407898480892, LastAccessTime = 1407898482499 ]
    [ key = A, value=Some Value, version=1, hitCount=3, CreationTime = 1407898480892, LastAccessTime = 1407898484099 ]
    [ key = A, value=Some Value, version=1, hitCount=4, CreationTime = 1407898480892, LastAccessTime = 1407898485699 ]
    null

    关于这二个参数的设置,个人建议是:

    a) 如果缓存的数据本身不存在更新(比如:一些几乎从来不动的基础数据),只设置timeToIdleSeconds,这样的好处是,如果缓存项一直有人在访问,就永远不会过期,反之,如果没人用,空闲一段时间后,会自动过期,释放资源

    b) 如果缓存的数据本身存在定期的更新问题(比如:天气预报之类每隔几小时,db中会更新的数据),可同时设置二个参数,timeToLiveSeconds的值应该要小于db中的更新周期,这样db中的数据变化后,过一段时间就会更新到缓存中

  • 相关阅读:
    DateTime.now()用法
    C#中静态类详述
    面向对象详述
    解决Github打不开问题
    git 提交代码流程 先暂存 在提交+备注 然后拉取代码获取最新的代码 然后再推送 git push
    常用
    样式重置
    Html 5优化
    理解js闭包
    css 倒计时 svg
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/3908570.html
Copyright © 2020-2023  润新知