前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ehcache2.8.3入门示例:hello world

ehcache2.8.3入门示例:hello world

作者头像
菩提树下的杨过
发布2018-01-24 11:41:24
7140
发布2018-01-24 11:41:24
举报
文章被收录于专栏:菩提树下的杨过

一、pom.xml 依赖项

代码语言:javascript
复制
 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>

二、ehcache.xml

代码语言:javascript
复制
 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>

三、示例代码

代码语言:javascript
复制
 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 \t= " + 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 \t= " + 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 \t= " + eleJimmy.getObjectValue());
52         }
53 
54         // 取出一个不存在的缓存项
55         System.out.println("fake \t= " + cache2.get("fake"));
56 
57         manager.shutdown();
58     }
59 
60 }

运行结果:

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

四、关于timeToLiveSeconds、timeToIdleSeconds

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

代码语言:javascript
复制
  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     }

结论:

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:

代码语言:javascript
复制
 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     }

输出结果

[ 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:

代码语言:javascript
复制
 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     }

输出结果

[ 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:

代码语言:javascript
复制
 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     }

输出结果

[ 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中的数据变化后,过一段时间就会更新到缓存中

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014-08-12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档