Ehcache高并发在项目中的应用

来源:互联网 发布:网络推广手段 编辑:程序博客网 时间:2024/05/17 13:41

我们在项目开发中,有些数据常常用到,而又不需要经常去更新它,我们就会想到了使用缓存来保存这些数据,已提高我们对这些数据的读取速度,因此本文使用ehcache来解决这个问题,EhcacheUtil 能有效的防止高并发。

ehcache的jar包下载地址为:http://ehcache.org/downloads/destination?name=ehcache-2.9.0-distribution.tar.gz&bucket=tcdistributions&file=ehcache-2.9.0-distribution.tar.gz ,下载后引用lib目录下的ehcache-2.9.0.jar、slf4j-api-1.7.7.jar、slf4j-jdk14-1.7.7.jar。


1、EhcacheUtil 类

/** * 高并发解析: * 1、当一个线程获取了某一Key的Read锁之后,其它线程获取针对于同一个Key的Read锁不会受到限制, * 但其它线程(包括获取了该Key的Read锁的线程)如果想获取针对同一个Key的Write锁就不行,它需要等到针对于该Key的Read锁释放后才能获取其Write锁; * 2、当一个线程获取了某一Key的Write锁之后,其它线程获取同一个Key的Read锁或者Write锁的请求将等待针对于该Key的Write锁释放后才能继续进行, * 但是同一个线程获取该Key对应的Read锁或者Write锁将不需要等待。 * 获取了对应的锁之后,不再需要该锁后释放该锁,以免引起死锁。 */public class EhcacheUtil {private static final String PATH = "/ehcache.xml";private static final String CACHE_NAME = "productEhcache";private CacheManager manager;private static EhcacheUtil ehCache;private EhcacheUtil(String path) {URL url = getClass().getResource(path);manager = CacheManager.create(url);}/** * 获取缓存实例,配置文件路径“src/ehcache.xml” * @return */public static EhcacheUtil getInstance() {if (ehCache == null) {ehCache = new EhcacheUtil(PATH);}return ehCache;}/** * 存储键值到默认的缓存里面 * @param key 键名 * @param value 键值 */public void put(String key, Object value) {put(CACHE_NAME, key, value);}/** * 存储键值到指定的缓存里面 * @param cacheName 缓存名称 * @param key 键名 * @param value 键值 */public void put(String cacheName, String key, Object value) {Cache cache = manager.getCache(cacheName);cache.acquireWriteLockOnKey(key);try {Element element = new Element(key, value);cache.put(element);} finally {cache.releaseWriteLockOnKey(key);} }/** * 从默认的缓存里面获取键值 * @param key 键名 */public Object get(String key) {return get(CACHE_NAME, key);}/** * 从指定的缓存里面获取键值 * @param cacheName 缓存名称 * @param key 键名 */public Object get(String cacheName, String key) {Cache cache = manager.getCache(cacheName);cache.acquireReadLockOnKey(key);Element element = null;try{element = cache.get(key);} finally {cache.releaseReadLockOnKey(key);} return element == null ? null : element.getObjectValue();}/** * 从默认的缓存里面删除键值 * @param key 键名 */public void remove(String key) {remove(CACHE_NAME, key);}/** * 从指定的缓存里面删除键值 * @param cacheName 缓存名称 * @param key 键名 */public void remove(String cacheName, String key) {Cache cache = manager.getCache(cacheName);cache.remove(key);}}
2、ehcache.xml配置文件,放到src根目录下面

<?xml version="1.0" encoding="UTF-8"?><!--   缓存配置   timeToIdleSeconds 当缓存闲置n秒后销毁。  timeToLiveSeconds 当缓存存活n秒后销毁。  name:缓存名称。   maxElementsInMemory:缓存最大个数。   eternal:对象是否永久有效,一但设置了,timeout将不起作用。   timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。   timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。   overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。   diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。   maxElementsOnDisk:硬盘最大缓存个数。   diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.   diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。   memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。   clearOnFlush:内存数量最大时是否清除。 --> <ehcache><diskStore path="java.io.tmpdir" />   <defaultCache maxElementsInMemory="500" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="1200" overflowToDisk="true" />    <cache name="testEhcache" maxElementsInMemory="150" eternal="false" timeToLiveSeconds="36000" timeToIdleSeconds="3600" overflowToDisk="true"/>      <cache name="productEhcache" maxElementsInMemory="500" memoryStoreEvictionPolicy="LRU" eternal="true" diskSpoolBufferSizeMB="1024" overflowToDisk="true"/>  </ehcache>  
3、EhcacheTest测试类

public class EhcacheTest {//新建ehcache实例private static EhcacheUtil ehcache = EhcacheUtil.getInstance();public static void main(String[] args) {setProductData();ProductDto pd = (ProductDto)ehcache.get(Constant.PRODUCT_MAP_CACHE_NAME+1);System.out.println(pd);ehcache.remove(Constant.PRODUCT_MAP_CACHE_NAME+1);pd = (ProductDto)ehcache.get(Constant.PRODUCT_MAP_CACHE_NAME+1);System.out.println(pd);}public static void setProductData(){//构造数据int sizeProduct = 100000;//List<ProductDto> productList = new ArrayList<ProductDto>();for (int j = 0; j < sizeProduct; j++) {//ProductDto product = new ProductDto();//product.setId(j);//product.setProductName("产品名称"+j);////productList.add(product);//ehcache.put(Constant.PRODUCT_MAP_CACHE_NAME+j, product);ehcache.put(Constant.PRODUCT_MAP_CACHE_NAME+j, j);}//把map放到ehcache中//ehcache.put(Constant.PRODUCT_MAP_CACHE_NAME, productList);}@SuppressWarnings("unchecked")public static List<ProductDto> getProductData(){return (List<ProductDto>)ehcache.get(Constant.PRODUCT_MAP_CACHE_NAME);}public static void deleteProductData(int index){List<ProductDto> productList = getProductData();productList.remove(productList.get(index));ehcache.put(Constant.PRODUCT_MAP_CACHE_NAME, productList);}public static void addProductData(int index){List<ProductDto> productList = getProductData();ProductDto product = new ProductDto();product.setId(index);product.setProductName("产品名称"+index);productList.add(product);ehcache.put(Constant.PRODUCT_MAP_CACHE_NAME, productList);}public static void showProductData(){List<ProductDto> productList = getProductData();System.out.println("---------------------");for (ProductDto productDto : productList) {System.out.println(productDto);}}}
4、ProductDto实体类
public class ProductDto implements java.io.Serializable {private static final long serialVersionUID = 1L;private Integer id;//idprivate String productName;//产品名称public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getProductName() {return productName;}public void setProductName(String productName) {this.productName = productName;}public String toString(){return this.getId()+" ,name:"+this.getProductName();}}
5、Constant静态变量类

public class Constant {/** * 产品MAP */public static final String PRODUCT_MAP_CACHE_NAME = "productMap";}





0 0
原创粉丝点击