对于一个数据对象,我们首先存储在数据库中,如果有需要我们还可以存在缓存中,比如memcached,redis等缓存技术,当然还可以结合Ehcache使用,在我工作中接触的项目中就是这样使用的,对获取一个数据对象,先从Ehcache获取,如果没有获取到,再从memcache获取。
所以有必要对Ehcache的使用有一个认识:
使用Ehcache当然要引入Ehcache相关的jar包:(工程中的代码以及jar包在博文后面会有分享。)
Ehcache的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false">
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="100000" eternal="false"
overflowToDisk="true" timeToIdleSeconds="120" timeToLiveSeconds="120"
diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LFU" />
<!--这里设置了缓存失效时间10秒(timeToLiveSeconds)-->
<cache name="testCache" maxElementsInMemory="20000" eternal="false"
overflowToDisk="false" timeToIdleSeconds="1800" timeToLiveSeconds="10"
memoryStoreEvictionPolicy="LFU">
</cache>
</ehcache>
配置文件说明:
name:设置缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskPersistent:是否在VM重启时存储硬盘的缓存数据。默认值是false。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)
缓存策略:
LRU - least recently used(最近最少使用)
LFU - least frequently used(最不经常使用)
FIFO - first in first out, the oldest element by creation time(清除最早缓存的数据,不关心是否经常使用)
简单使用:
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
public class EhcacheTest {
public static void main(String[] args) {
String ecacheName="testCache";
CacheManager cacheManager=CacheManager.create("ehcache.xml");
Cache cache=cacheManager.getCache(ecacheName);
//存缓存
Element element=new Element(ecacheName, "Hello Cache!");
cache.put(element);
//测试取缓存
Element el=cache.get(ecacheName);
String value=el.getObjectValue().toString();
System.out.println(value);
//测试缓存失效时间,这里让线程休眠time时间
//配置文件设置10秒缓存失效,可以设置time大于和小于10秒的情况
long time=9000;
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
//第二次取缓存
Element el2=cache.get(ecacheName);
String value2=el2.getObjectValue().toString();
System.out.println(value2);
测试结果:
在timeToLiveSeconds有效期内是可以随时取到缓存的数据,代码中通过线程休眠模拟缓存失效后的效果,如果time时间设置大于timeToLiveSeconds,通过代码是取不到数据的。
为了方便使用,可以新建一个Ehcache缓存的工具类:
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
public class EhcacheUtil {
private static final String path = "ehcache.xml";
private CacheManager manager;
private static EhcacheUtil ehCache;
private EhcacheUtil(String path) {
manager = CacheManager.create(path);
}
public static EhcacheUtil getInstance() {
if (ehCache == null) {
ehCache = new EhcacheUtil(path);
}
return ehCache;
}
public void put(String cacheName, String key, Object value) {
Cache cache = manager.getCache(cacheName);
Element element = new Element(key, value);
cache.put(element);
}
public Object get(String cacheName, String key) {
Cache cache = manager.getCache(cacheName);
Element element = cache.get(key);
return element == null ? null : element.getObjectValue();
}
public Cache get(String cacheName) {
return manager.getCache(cacheName);
}
public void remove(String cacheName, String key) {
Cache cache = manager.getCache(cacheName);
cache.remove(key);
}
}
使用:
EhcacheUtil ehcacheUtil=EhcacheUtil.getInstance();
ehcacheUtil.put(ecacheName, "test2", "Hello Cache2");
long time2=15000;
try {
Thread.sleep(time2);
} catch (InterruptedException e) {
e.printStackTrace();
}
String value3=ehcacheUtil.get(ecacheName, "test2").toString();
System.out.println(value3);