备忘:ehcache的简单使用说明

ehcache 中的主要概念

  1. CacheManager:缓存管理器。负责Cache的创建、访问、移除。
  2. Cache:缓存实例。所有的cache都实现了接口Ehcache。每个cache都有名字和属性,且包含N个Element。
  3. Element:存放于Cache中的原子单位。有一个key、一个value以及关于访问的记录。Element被放进到Cache或者被从Cache移除。Element也可能会由于过期被移除,这依赖于Cache的配置。

本文中使用的相关软件版本

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.4</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

log4j 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
<log4j:configuration>
    <!--输出到控制台 -->
    <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n" />
        </layout>
    </appender>

    <logger name="org.springframework">
        <level value="INFO"/>
    </logger>
    <logger name="net.sf.ehcache">
        <level value="DEBUG"/>
    </logger>

    <root>
        <level value="INFO" />
        <appender-ref ref="consoleAppender" />
    </root>
</log4j:configuration>

代码方式使用ehcache

public static void main(String[] args) {  
    // 创建缓存管理器
    CacheManager cm1 = CacheManager.create();
    // 创建一个缓存实例
    Cache myCache = new Cache("myCache", 5000, false, false, 5, 2);

    // 在缓存管理器中添加缓存实例
    cm1.addCache(myCache);

    // 在缓存管理器中获取一个缓存实例
    // oneCache = cm1.getCache("oneCache");

    myCache.put(new Element("key1", "value1"));// 添加缓存元素
    myCache.put(new Element("key2", "value2"));// 添加缓存元素

    int elementCount = myCache.getSize();// 获取缓存元素个数

    System.out.printf("缓存%s中Elemet个数为:%s\n", "myCache", elementCount);

    // 获取对象值
    Element el = myCache.get("key1");
    Object obj = el.getObjectValue();
    System.out.printf("Element Key:%s,Value:%s\n", "key1", obj.toString());
    // 删除缓存
    myCache.remove("key1");
    if (myCache.isKeyInCache("key1")) {
        System.out.println("Element: key1 IN myCache");
    } else {
        System.out.println("Element: key1 NOT IN myCache");
    }

    CacheManager cm2 = CacheManager.create();
    System.out.println(cm1 == cm2);
}  

xml方式使用ehcache

配置ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ehcacheDemo">

    <!-- 磁盘缓存位置 -->
    <diskStore path="java.io.tmpdir" />

    <!--没有特殊设置时系统默认使用此设置 -->
    <defaultCache maxElementsInMemory="1000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        maxElementsOnDisk="10000" diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />

    <cache name="demoCache" maxElementsInMemory="2000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        memoryStoreEvictionPolicy="LRU" />
</ehcache>

maxElementsInMemory:cache中最多可以存放的元素的数量。

如果放入cache中的元素超过这个数值,有两种情况:
1. 若overflowToDisk的属性值为true,会将cache中多出的元素放入磁盘文件中。
2. 若overflowToDisk的属性值为false,会根据memoryStoreEvictionPolicy的策略替换cache中原有的元素。

eternal:是否永驻内存。

如果值是true,cache中的元素将一直保存在内存中,不会因为时间超时而丢失。
所以这个值设置为true时,timeToIdleSeconds和timeToLiveSeconds两个属性的值就不起作用了。

timeToIdleSeconds:访问cache中元素的最大间隔时间。

如果超过这个时间没有访问这个cache中的某个元素,那么这个元素将被从cache中清除。

timeToLiveSeconds:cache中元素的生存时间。

cache中的某个元素从创建到消亡的时间,从创建开始计时,当超过这个时间,这个元素将被从cache中清除。

overflowToDisk :

溢出是否写入磁盘。系统会根据标签<diskStore path="java.io.tmpdir"/>中path的值查找对应的属性值。

diskExpiryThreadIntervalSeconds:磁盘缓存的清理线程运行间隔

每经过多少秒,执行一次清理线程

memoryStoreEvictionPolicy:内存存储与释放策略。

LRU -Least Recently Used
LFU -Least Frequently Used
FIFO-First In First Out, the oldest element by creation time

diskPersistent:是否持久化磁盘缓存。

当这个属性的值为true时,系统在初始化的时候会在磁盘中查找文件名为cache名称,后缀名为index的的文件,如CACHE_FUNC.index。
这个文件中存放了已经持久化在磁盘中的cache的index,找到后把cache加载到内存。
要想把cache真正持久化到磁盘,写程序时必须注意,在是用net.sf.ehcache.Cache的void put (Element element)方法后要使用void flush()方法。

代码

public static void main(String[] args) {
    String cacheName = "demoCache";// 与ehcache.xml中的cache.name对应
    String elementKey = "k1";

    // 创建缓存管理器
    CacheManager cm1 = new CacheManager();

    // 根据cacheName取得cache的实例
    Cache cache = cm1.getCache(cacheName);

    // 将数据Element放入到cache实例中
    cache.put(new Element(elementKey, "Element_1"));

    // 取值
    Cache cache2 = cm1.getCache(cacheName);
    Element element = cache2.get(elementKey);

    // Print the value
    System.out.printf("cache2中element保存的值为:%s\n", element.getObjectValue());
}  

CacheManager创建模式

单例模式

在代码中使用CacheManager.create(…)创建CacheManager,返回的是已经存在的ehcache.xml配置对应的单例CacheManager,如果不存在,则创建一个。
参考 net.sf.ehcache.CacheManager 的代码:

    /**
     * Default name if not specified in the configuration/
     */
    public static final String DEFAULT_NAME = "__DEFAULT__";

    /**
     * The Singleton Instance.
     */
    private static volatile CacheManager singleton;

    ......

    public static CacheManager create() throws CacheException {
        if (singleton != null) {
            LOG.debug("Attempting to create an existing singleton. Existing singleton returned.");
            return singleton;
        }
        synchronized (CacheManager.class) {
            if (singleton == null) {
                singleton = newInstance();
            } else {
                LOG.debug("Attempting to create an existing singleton. Existing singleton returned.");
            }
            return singleton;
        }
    }
    ......
     private static CacheManager newInstance(Configuration configuration, String msg) throws CacheException {
        synchronized (CacheManager.class) {
            String name = configuration.getName();
            if (name == null) {
                name = DEFAULT_NAME;
            }
            CacheManager cacheManager = CACHE_MANAGERS_MAP.get(name);
            if (cacheManager == null) {
                LOG.debug(msg);
                cacheManager = new CacheManager(configuration);
            }
            return cacheManager;
        }
    }

多实例模式

在代码中使用new CacheManager(…)方法创建CacheManger,每次调用都会返回一个新的CacheManger。

注意:2.5之后的版本,不允许在同一个JVM中有多个相同名字的CacheManager。

也就是说,如果在代码中使用

CacheManager cm1 = new CacheManager();
CacheManager cm2 = new CacheManager();

会报错。

Exception in thread "main" net.sf.ehcache.CacheException: Another CacheManager with same name 'ehcacheDemo' already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.

因为new CacheManger()没有指定各自的配置文件,所以都加载了classpath下的ehcache.xml,导致了CacheManger的名字(即:ehcacheDemo)冲突。

所以程序中要使用两个CacheManager的话,只要修改下设置一下就可以了。
1. 不同的配置文件:ehcache1.xml,ehcache2.xml
2. 不同的ehcache.name:ehcacheDemo1,ehcacheDemo2。
3. 不同的构造参数:

CacheManager cm1 = new CacheManager(TestEhcache.class.getResourceAsStream("/ehcache1.xml"));
CacheManager cm2 = new CacheManager(TestEhcache.class.getResourceAsStream("/ehcache2.xml"));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值