java缓存——(五)LocalCache本地缓存分享

java缓存——(五)LocalCache本地缓存分享

LocalCache本地缓存分享

前言

一、本地缓存应用场景

二、java本地缓存标准

三、java开源缓存框架

四、LocalCache实现

结束语

前言

本次分享探讨java平台的本地缓存,是指占用JVM的heap区域来缓冲存储数据的缓存组件。

一、本地缓存应用场景

localcache有着极大的性能优势:

1. 单机情况下适当使用localcache会使应用的性能得到很大的提升。

2. 集群环境下对于敏感性要求不高的数据可以使用localcache,只配置简单的失效机制来保证数据的相对一致性。

哪些数据可以存储到本地缓存?

1.访问频繁的数据;

2.静态基础数据(长时间内不变的数据);

3.相对静态数据(短时间内不变的数据)。

二、java本地缓存标准

Java缓存新标准(javax.cache),这个标准由JSR107所提出,已经被包含在Java EE 7中。

特性:

1.原子操作,跟java.util.ConcurrentMap类似

2.从缓存中读取

3.写入缓存

4.缓存事件监听器

5.数据统计

6.包含所有隔离(ioslation)级别的事务

7.缓存注解(annotations)

8.保存定义key和值类型的泛型缓存

9.引用保存(只适用于堆缓存)和值保存定义

但目前应用不是很普遍。

三、java开源缓存框架

比较有名的本地缓存开源框架有:

1.EHCache

EHCache是一个纯java的在进程中的缓存,它具有以下特性:快速,简单,为Hibernate2.1充当可插入的缓存,最小的依赖性,全面的文档和测试。

BUG: 过期失效的缓存元素无法被GC掉,时间越长缓存越多,内存占用越大,导致内存泄漏的概率越大。

2.OSCache

OSCache有以下特点:缓存任何对象,你可以不受限制的缓存部分jsp页面或HTTP请求,任何java对象都可以缓存。拥有全面的API--OSCache API给你全面的程序来控制所有的OSCache特性。永久缓存--缓存能随意的写入硬盘,因此允许昂贵的创建(expensive-to-create)数据来保持缓存,甚至能让应用重启。支持集群--集群缓存数据能被单个的进行参数配置,不需要修改代码。缓存记录的过期--你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。

3.JCache

Java缓存新标准(javax.cache)

4.cache4j

cache4j是一个有简单API与实现快速的Java对象缓存。它的特性包括:在内存中进行缓存,设计用于多线程环境,两种实现:同步与阻塞,多种缓存清除策略:LFU, LRU, FIFO,可使用强引用。

5.ShiftOne

ShiftOne Java Object Cache是一个执行一系列严格的对象缓存策略的Java lib,就像一个轻量级的配置缓存工作状态的框架。

6.WhirlyCache

Whirlycache是一个快速的、可配置的、存在于内存中的对象的缓存。

四、LocalCache实现

1、LocalCache简介

LocalCache是一个精简版本地缓存组件,有以下特点:

1. 有容量上限maxCapacity;

2. 缓存达到容量上限时基于LRU策略来移除缓存元素;

3. 缓存对象的生命周期(缓存失效时间)由调用方决定;

4. 缓存对象失效后,将会有定时清理线程来清理掉,不会导致内存泄漏。

5. 性能比Ehcache稍强。

2、总体设计

LocalCache总体设计:

1. 缓存元素 CacheElement;

2. 缓存容器 LRULinkedHashMap;

3. 缓存接口 Cache;

4. 缓存组件实现 LocalCache。

3、详细设计

1. CacheElement设计

/**

* 缓存元素

*

*/

public class CacheElement {

private Object key;

private Object value;

private long createTime;

private long lifeTime;

private int hitCount;

public CacheElement() {

}

public CacheElement(Object key ,Object value) {

this.key = key;

this.value = value;

this.createTime = System.currentTimeMillis();

}

public Object getKey() {

return key;

}

public void setKey(Object key) {

this.key = key;

}

public Object getValue() {

hitCount++;

return value;

}

public void setValue(Object value) {

this.value = value;

}

public long getCreateTime() {

return createTime;

}

public void setCreateTime(long createTime) {

this.createTime = createTime;

}

public int getHitCount() {

return hitCount;

}

public void setHitCount(int hitCount) {

this.hitCount = hitCount;

}

public long getLifeTime() {

return lifeTime;

}

public void setLifeTime(long lifeTime) {

this.lifeTime = lifeTime;

}

public boolean isExpired() {

boolean isExpired = System.currentTimeMillis() - getCreateTime() > getLifeTime();

return isExpired;

}

/*

* (non-Javadoc)

* @see java.lang.Object#toString()

*/

public String toString() {

StringBuffer sb = new StringBuffer();

sb.append("[ key=").append(key).append(", isExpired=").append(isExpired())

.append(", lifeTime=").append(lifeTime).append(", createTime=").append(createTime)

.append(", hitCount=").append(hitCount)

.append(", value=").append(value).append(" ]");

return sb.toString();

}

/*

* (non-Javadoc)

* @see java.lang.Object#hashCode()

*/

public final int hashCode(){

if(null == key){

return "".hashCode();

}

return this.key.hashCode();

}

/*

* (non-Javadoc)

* @see java.lang.Object#equals(java.lang.Object)

*/

public final boolean equals(Object object) {

if ((object == null) || (!(object instanceof CacheElement))) {

return false;

}

CacheElement element = (CacheElement) object;

if ((this.key == null) || (element.getKey() == null)) {

return false;

}

return this.key.equals(element.getKey());

}

}

2. LRULinkedHashMap实现

import java.util.LinkedHashMap;

import java.util.Set;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

/**

* 实现 LRU策略的 LinkedHashMap

*

* @param

* @param

*/

public class LRULinkedHashMap extends LinkedHashMap

{

protected static final long serialVersionUID = 2828675280716975892L;

protected static final int DEFAULT_MAX_ENTRIES = 100;

protected final int initialCapacity;

protected final int maxCapacity;

protected boolean enableRemoveEldestEntry = true;//是否允许自动移除比较旧的元素(添加元素时)

protected static final float DEFAULT_LOAD_FACTOR = 0.8f;

protected final Lock lock = new ReentrantLock();

public LRULinkedHashMap(int initialCapacity)

{

this(initialCapacity, DEFAULT_MAX_ENTRIES);

}

public LRULinkedHashMap(int initialCapacity ,int maxCapacity)

{

//set accessOrder=true, LRU

super(initialCapacity, DEFAULT_LOAD_FACTOR, true);

this.initialCapacity = initialCapacity;

this.maxCapacity = maxCapacity;

}

/*

* (non-Javadoc)

* @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry)

*/

protected boolean removeEldestEntry(java.util.Map.Entry eldest)

{

return enableRemoveEldestEntry && ( size() > maxCapacity );

}

/*

* (non-Javadoc)

* @see java.util.LinkedHashMap#get(java.lang.Object)

*/

public V get(Object key)

{

try {

lock.lock();

return super.get(key);

}

finally {

lock.unlock();

}

}

/*

* (non-Javadoc)

* @see java.util.HashMap#put(java.lang.Object, java.lang.Object)

*/

public V put(K key, V value)

{

try {

lock.lock();

return super.put(key, value);

}

finally {

lock.unlock();

}

}

/*

* (non-Javadoc)

* @see java.util.HashMap#remove(java.lang.Object)

*/

public V remove(Object key) {

try {

lock.lock();

return super.remove(key);

}

finally {

lock.unlock();

}

}

/*

* (non-Javadoc)

* @see java.util.LinkedHashMap#clear()

*/

public void clear() {

try {

lock.lock();

super.clear();

}

finally {

lock.unlock();

}

}

/*

* (non-Javadoc)

* @see java.util.HashMap#keySet()

*/

public Set keySet() {

try {

lock.lock();

return super.keySet();

}

finally {

lock.unlock();

}

}

public boolean isEnableRemoveEldestEntry() {

return enableRemoveEldestEntry;

}

public void setEnableRemoveEldestEntry(boolean enableRemoveEldestEntry) {

this.enableRemoveEldestEntry = enableRemoveEldestEntry;

}

public int getInitialCapacity() {

return initialCapacity;

}

public int getMaxCapacity() {

return maxCapacity;

}

}

3. Cache接口设计

/**

* 缓存接口

*

*/

public interface Cache {

/**

* 获取缓存

* @param key

* @return

*/

public T getCache(Object key);

/**

* 缓存对象

* @param key

* @param value

* @param milliSecond 缓存生命周期(毫秒)

*/

public void putCache(Object key, Object value ,Long milliSecond);

/**

* 缓存容器中是否包含 key

* @param key

* @return

*/

public boolean containsKey(Object key);

/**

* 缓存列表大小

* @return

*/

public int getSize();

/**

* 是否启用缓存

*/

public boolean isEnabled();

/**

* 启用 或 停止

* @param enable

*/

public void setEnabled(boolean enabled);

/**

* 移除所有缓存

*/

public void invalidateCaches();

/**

* 移除 指定key缓存

* @param key

*/

public void invalidateCache(Object key);

}

4. LocalCache实现

import java.util.Date;

import java.util.Iterator;

import java.util.Random;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

/**

* 本地缓存组件

*/

public class LocalCache implements Cache{

private Logger logger = LoggerFactory.getLogger(this.getClass());

private LRULinkedHashMap

结束语

开源或有BUG,入手需谨慎。

原文:https://blog.csdn.net/u011683530/article/details/51029734

相关推荐

DNF每日必刷:超时空攻略,轻松通关拿奖励
365下载手机版

DNF每日必刷:超时空攻略,轻松通关拿奖励

📅 08-25 👁️ 3677
常用国字标准字体表
365下载手机版

常用国字标准字体表

📅 07-27 👁️ 845
《我的世界》铁路系统教程 从小白到大师
365赢了不让提款

《我的世界》铁路系统教程 从小白到大师

📅 01-19 👁️ 9387