ehcache 上层加工自己的cache

来源:互联网 发布:plc编程工作 编辑:程序博客网 时间:2024/04/28 01:20

ehcache 在使用的时候,其实自己的实现已经很好了,它的内部实现有两种实现的方式:一种是内存的缓存方式,只存在内存,用完就删除了,只会和内存有关系:主要分为按

对应的elements的多少来存储,或者是指定内存大小来存储;第二种内存是存磁盘,就是写到硬盘上去,这种的好处就是不管你内存多大,都可以不用管,把内容写到磁盘上去,那么问题就来,我想先在内存存数据,然后内存不够的时候我想让写磁盘,那么这种需求该如何去实现呐 ?

 

可以肯定的是:现在ehcache本身是实现不了的,我早就已经测试过了,那么如何才能达到这种要求呐 ?

具体做法如下:

1.在cache 的管理层cachemanager中去管理cache 。

2.在定义自己的cache,实现 CacheEventListener  针对内部的notifyElementEvicted ,将cache移除的数据写入到磁盘上去。

3.让自己的cache被cachemanager去管理就好。


源码下载地址:http://download.csdn.net/detail/supingemail/8734915


具体代码如下:


MCache:


public class MCache implements CacheEventListener {

private String cacheName;

private Cache cache;

private String filePath;

public Map<String, File> selfCache = new HashMap<String, File>();


public MCache(String cacheName, Cache cache, CacheManager cacheManager) {
this.cacheName = cacheName;
this.cache = cache;
cache.getCacheEventNotificationService().registerListener(this);
filePath = cacheManager.getConfiguration().getDiskStoreConfiguration().getPath(); 
}


public Object get(String key) {
try {
if (cache.get(key) != null) {
return cache.get(key);
} else {
if (selfCache.get(key) != null) {
File file = selfCache.get(key);
InputStream is  =  new FileInputStream(file);
DataInputStream dis = new DataInputStream(is);
//class
String className = dis.readUTF();
WriteableObject wObject = (WriteableObject) Class.forName(className).newInstance();
wObject.read(is);
put(key, wObject);
return wObject;
} else {
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}


public boolean put(String key, Object value) {
try {
cache.put(new Element(key, value));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}


@Override
public void notifyElementRemoved(Ehcache cache, Element element)
throws CacheException {
}


@Override
public void notifyElementPut(Ehcache cache, Element element)
throws CacheException {
}


@Override
public void notifyElementUpdated(Ehcache cache, Element element)
throws CacheException {
}


@Override
public void notifyElementExpired(Ehcache cache, Element element) {
}


@Override
public void notifyElementEvicted(Ehcache cache, Element element) {
WriteableObject wObject = (WriteableObject) element.getObjectValue();
String key = (String) element.getObjectKey();
File file = new File(filePath + key + ".dat");
selfCache.put((String) element.getObjectKey(), file);
try {
OutputStream outputStream = new FileOutputStream(file);
DataOutputStream dos = new DataOutputStream(outputStream);
try {
dos.writeUTF(wObject.getClass().getName());
wObject.write(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}


@Override
public void notifyRemoveAll(Ehcache cache) {
}


@Override
public void dispose() {

}


public Object clone() {
return this;
}


public String getCacheName() {
return cacheName;
}


public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}


public Cache getCache() {
return cache;
}


public void setCache(Cache cache) {
this.cache = cache;
}


}


MCacheManager :


public class MCacheManager {

private static Logger logger = LoggerFactory.getLogger(MCacheManager.class.getName());

private Map<Object, MCache> cacheMap = new HashMap<Object, MCache>();

private static String CACHE_PATH = "java.io.tmpdir";

private static String MAX_MEMORY = "512m";

private static final String BLOCK_MAX_MEMORY = "512m";


private static MCacheManager instance = null;

private Properties props = null;

private CacheManager cacheManager = null;

private Cache memoryCache = null;

private MCache dataCache = null;

private static final String removePolicy = "LFU";

public static MCacheManager getInstance() {
if (instance == null) {
synchronized (MCacheManager.class) {
if (instance == null) {
instance = new MCacheManager();
}
}
}
return instance;
}


private MCacheManager() {
super();
double maxMemory = (Runtime.getRuntime().maxMemory() * 0.4) / (1024 * 1024);// m
MAX_MEMORY = maxMemory + "";
}


public Cache memoryCache() {
if (memoryCache == null) {
synchronized (this) {
if (memoryCache == null) {
String maxMemory = getProperty("block.cache.max.memory",BLOCK_MAX_MEMORY);
memoryCache = getCache("__memoryCache__", maxMemory, false);
}
}
}
return memoryCache;
}


public MCache dataCache(String cacheName ,Cache cache , CacheManager cacheManager) {
if (dataCache == null) {
synchronized (this) {
if (dataCache == null) {
dataCache = new MCache(cacheName, cache, cacheManager);
}
}
}
return dataCache;
}

public Cache getCache(String cacheName, String maxMemory ) {
Cache cache = getCacheManager().getCache(cacheName);
if (cache == null) {
synchronized (this) {
cache = getCacheManager().getCache(cacheName);
if (cache == null) {
CacheConfiguration cacheConfig = new CacheConfiguration();
cacheConfig.name(cacheName);
cacheConfig.eternal(false);
String removeTag = getProperty("cache.remove.tag", removePolicy);
cacheConfig.setMemoryStoreEvictionPolicy(removeTag);
cacheConfig.setOverflowToDisk(false);
cacheConfig.setDiskPersistent(false);
cacheConfig.setMaxBytesLocalHeap(maxMemory);
cache = new Cache(cacheConfig);
getCacheManager().addCache(cache);
}
}
}
return cache;
}

private Cache getCache(String cacheName, String maxMemory, boolean saveDisk) {
Cache cache = getCacheManager().getCache(cacheName);
if (cache == null) {
synchronized (this) {
cache = getCacheManager().getCache(cacheName);
if (cache == null) {
CacheConfiguration cacheConfig = new CacheConfiguration();
cacheConfig.name(cacheName);
cacheConfig.eternal(false);
String removeTag = getProperty("cache.remove.tag", removePolicy);
cacheConfig.setMemoryStoreEvictionPolicy(removeTag);
cacheConfig.setOverflowToDisk(saveDisk);
cacheConfig.setDiskPersistent(false);
cacheConfig.setMaxBytesLocalHeap(maxMemory);
cache = new Cache(cacheConfig);
getCacheManager().addCache(cache);
}
}
}
return cache;
}


public CacheManager getCacheManager() {
if (cacheManager == null) {
synchronized (this) {
if (cacheManager == null) {
Configuration configuration = new Configuration();
DiskStoreConfiguration dscg = new DiskStoreConfiguration();
String cacheFilePath = getProperty("cache.path.disk", CACHE_PATH);
File file = new File(cacheFilePath);
if (!file.exists()) {
file.mkdirs();
}
CACHE_PATH = cacheFilePath;
dscg.setPath(cacheFilePath);
configuration.diskStore(dscg);
configuration.setMaxBytesLocalHeap(getProperty("cache.manager.max.memory", MAX_MEMORY));
configuration.setDynamicConfig(true);
configuration.setMonitoring("autodetect");
configuration.setUpdateCheck(false);
cacheManager = new CacheManager(configuration);
}
}
}
return cacheManager;
}



public void addCache(MCache mCache){
cacheMap.put(mCache.getCacheName(), mCache);
}


public MCache get(String cacheName){
if (cacheMap.containsKey(cacheName)) {
return (MCache) cacheMap.get(cacheName);
}else {
return null;
}
}


private String getProperty(String key, String defaultValue) {
if (props == null) {
synchronized (this) {
if (props == null) {
try {
InputStream stream = Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream("/cache.properties");
if (stream == null) {
stream = MCacheManager.class
.getResourceAsStream("/cache.properties");
}
props = new Properties();
props.load(stream);
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}
}
return props.getProperty(key, defaultValue);
}



private boolean deleteCache(){
File file = new File(CACHE_PATH);
File[] folderFiles  = file.listFiles();
for (File f : folderFiles) {
f.delete();
}
return true;
}

}



写磁盘 WriteableObject  接口


public interface WriteableObject extends Serializable {

public void read(InputStream inputStream) throws IOException;

public boolean write(OutputStream outputStream) throws IOException;

}



实例类PersonBean :



public class PersonBean implements WriteableObject{


private static final long serialVersionUID = 1L;


private String name;


private List<String> list;

public PersonBean(){
super();
}

public PersonBean(String name, List<String> list) {
this.name = name;
this.list = list;
}


@Override
public void read(InputStream inputStream) throws IOException {
DataInputStream dis = new DataInputStream(inputStream);
name = dis.readUTF();
int size = dis.readInt();
list = new ArrayList<>();
for (int i = 0; i < size; i++) {
list.add(dis.readLine());
}
}


@Override
public boolean write(OutputStream outputStream) throws IOException {
DataOutputStream dos = new DataOutputStream(outputStream);
dos.writeUTF(name);
dos.writeInt(list.size());
for (String obj : list) {
dos.writeBytes(obj);
}
dos.close();
return true;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}


public List<String> getList() {
return list;
}


public void setList(List<String> list) {
this.list = list;
}


}


cache测试类Test :

public class Test {

static int index = 0;

public static void main(String[] args) throws IOException {

CacheManager cacheManager = MCacheManager.getInstance().getCacheManager(); 
Cache cache = MCacheManager.getInstance().memoryCache();
long maxMemory = cache.getCacheConfiguration().getMaxBytesLocalHeap();
System.out.println(" maxMemory = " + maxMemory / (1024 * 1024) + "mb");
MCache mCache = new MCache("testCache", cache,cacheManager);
MCacheManager.getInstance().addCache(mCache);

while (true) {
mCache.put("myCache" + index, beanInstance());
if (index > 100) {
String result = "----------------------" + index
+ "----------------------," + " \ncache.getSize() : "
+ cache.getSize() + ",\ncache.getDiskStoreSize() : "
+ cache.getDiskStoreSize() + ","
+ " \ncache.getMemoryStoreSize() : "
+ cache.getMemoryStoreSize() + ","
+ " \ncache.calculateInMemorySize() : "
+ cache.calculateInMemorySize()
+ ", \ncache.getKeys() : " + cache.getKeys()
+ ",\n keys size :" + cache.getKeys().size();
// buffer.append(result);
System.out.println(result);
break;
}
index++;
}

//List<String> keyList = mCache.
}



/**
* 放入数据到集合.

* @return
*/
private static PersonBean beanInstance() {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
list.add("JavaCache-EHCache系列之计算实例占用的内存大小(SizeOf引擎),基本数据的类型的大小是固定的,这里就不多说了。对于非基本类型的Java对象,其大小就值得商榷。加入的key是:"
+ i);
}
return new PersonBean("PersonBean"+index,list);
}


}


就这样,就完成了:先写内存,再写入磁盘的操作。。。

0 0
原创粉丝点击