`
zhangwei_david
  • 浏览: 476160 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java 本地缓存的实现

    博客分类:
  • Java
阅读更多

      在java web 项目中对频繁读取且相对稳定的数据一般都是用了缓存,这样可以极大地减少数据库的压力且提高的响应的速度。 一般都是,通过key 从缓存中读取value 如果value 为空则读取DB,将DB读取的数据再放入缓存这样的一个过程。

一个简易的本地缓存实现。

      首先数据一般都是有时效性的,不是放入缓存就一直存在,如果超过一定时间没有被使用则应当被清空,使其系统中不会使用到过期数据。

      下面是对本地缓存的一种简单实现

           首先定义一个缓存实体,包含三个属性 放入缓存的时间戳,值以及过期时间;其次需要个线程去监控缓存实体是否过期。

 

/**
*
* @author zhangwei_david
* @version $Id: CacheEntity.java, v 0.1 2014年9月6日 下午2:07:00 Lenovo Exp $
*/
/**
*本地缓存保存的实体
*
* @author Lenovo
* @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:13:43 Lenovo Exp $
*/
public class CacheEntity implements Serializable {

/** */
private static final long serialVersionUID = 7172649826282703560L;

/**
* 值
*/
private Object value;

/**
* 保存的时间戳
*/
private long gmtModify;

/**
* 过期时间
*/
private int expire;

public Object getValue() {
return value;
}

public void setValue(Object value) {
this.value = value;
}

public long getGmtModify() {
return gmtModify;
}

public void setGmtModify(long gmtModify) {
this.gmtModify = gmtModify;
}

public int getExpire() {
return expire;
}

public void setExpire(int expire) {
this.expire = expire;
}

public CacheEntity(Object value, long gmtModify, int expire) {
super();
this.value = value;
this.gmtModify = gmtModify;
this.expire = expire;
}

}

 

/**
* 简易本地缓存的实现类
* @author zhangwei_david
* @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:04:53 zhangwei_david Exp $
*/
public class LocalCache {
//默认的缓存容量
private static int DEFAULT_CAPACITY = 512;
//最大容量
private static int MAX_CAPACITY = 100000;
//刷新缓存的频率
private static int MONITOR_DURATION = 2;
// 启动监控线程
static {
new Thread(new TimeoutTimerThread()).start();
}
//使用默认容量创建一个Map
private static ConcurrentHashMap<String, CacheEntity> cache = new ConcurrentHashMap<String, CacheEntity>(
DEFAULT_CAPACITY);

/**
* 将key-value 保存到本地缓存并制定该缓存的过期时间
*
* @param key
* @param value
* @param expireTime 过期时间,如果是-1 则表示永不过期
* @return
*/
public boolean putValue(String key, Object value, int expireTime) {
return putCloneValue(key, value, expireTime);
}

/**
* 将值通过序列化clone 处理后保存到缓存中,可以解决值引用的问题
*
* @param key
* @param value
* @param expireTime
* @return
*/
private boolean putCloneValue(String key, Object value, int expireTime) {
try {
if (cache.size() >= MAX_CAPACITY) {
return false;
}
// 序列化赋值
CacheEntity entityClone = clone(new CacheEntity(value, System.nanoTime(), expireTime));
cache.put(key, entityClone);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}

/**
*
* 序列化 克隆处理
* @param object
* @return
*/
private <T extends Serializable> T clone(T object) {
T cloneObject = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
cloneObject = (T) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObject;
}

/**
*从本地缓存中获取key对应的值,如果该值不存则则返回null
*
* @param key
* @return
*/
public Object getValue(String key) {
return cache.get(key).getValue();

}

/**
* 清空所有
*/
public void clear() {
cache.clear();
}

/**
* 过期处理线程
*
* @author Lenovo
* @version $Id: LocalCache.java, v 0.1 2014年9月6日 下午1:34:23 Lenovo Exp $
*/
static class TimeoutTimerThread implements Runnable {
public void run() {
while (true) {
try {
System.out.println("Cache monitor");
TimeUnit.SECONDS.sleep(MONITOR_DURATION);
checkTime();
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* 过期缓存的具体处理方法
* @throws Exception
*/
private void checkTime() throws Exception {
//"开始处理过期 ";

for (String key : cache.keySet()) {
CacheEntity tce = cache.get(key);
long timoutTime = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()
- tce.getGmtModify());
//" 过期时间 : "+timoutTime);
if (tce.getExpire() > timoutTime) {
continue;
}
System.out.println(" 清除过期缓存 : " + key);
//清除过期缓存和删除对应的缓存队列
cache.remove(key);
}
}
}

}
3
2
分享到:
评论
4 楼 cfyme 2015-05-02  
学习了,实用
3 楼 zhangwei_david 2015-01-24  
是的,数据是有时效性的
2 楼 lzg406 2015-01-23  
dieslrae 写道
本地缓存你还去管它过不过期干啥,满了之后新put的把命中率最低的挤掉就好了

有些场合,必须考虑容器里面对象的生命周期,比如业务上已经不能移除不需要的数据,超时机制非常不错的。
1 楼 dieslrae 2015-01-23  
本地缓存你还去管它过不过期干啥,满了之后新put的把命中率最低的挤掉就好了

相关推荐

    Java利用ConcurrentHashMap实现本地缓存demo

    Java利用ConcurrentHashMap实现本地缓存demo; 基本功能有缓存有效期、缓存最大数、缓存存入记录、清理线程、过期算法删除缓存、LRU算法删除、获取缓存值等功能。 复制到本地项目的时候,记得改包路径哦~

    Java本地缓存的实现代码

    "Java本地缓存的实现代码" Java本地缓存的实现代码是指在Java应用中,使用本地缓存来提高访问频率高、更新少的数据的读取效率。在集群环境下,分布式缓存如Redis、Memcached等都是常用的选择,但是在单机环境下,...

    实现 Java 本地缓存的方法解析

    实现 Java 本地缓存的方法解析 本文主要介绍了实现 Java 本地缓存的方法解析,通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值。缓存肯定是项目中必不可少的,市面上有非常多的缓存工具,...

    如何基于LoadingCache实现Java本地缓存

    LoadingCache 是 Guava 库提供的一种缓存实现方式,本文将详细介绍如何基于 LoadingCache 实现 Java 本地缓存。 一、Guava 介绍 Guava 是 Google 开源的一套工具库,其中提供的 cache 模块非常方便,是一种与 ...

    java手写本地缓存示例

    基于java的map和timer实现本地缓存及定时清理失效缓存的功能 本项目仅用于初学者学习使用 初学者可基于此项目初步了解缓存实现的基本原理 后期在项目中使用建议使用现成的缓存框架:redis、ehcache等

    java 通过文件实现缓存

    java实现缓存可以通过读取本地文件的方式实现,改代码就是通过读取本地文件实现缓存的简单例子

    redis本地缓存与redis缓存

    本地缓存指的是将数据存储在应用程序的内存中,通常是Java的HashMap、Guava Cache或C#的MemoryCache等。这种方式的优点在于数据读取速度极快,因为避免了网络通信的延迟。但是,本地缓存的缺点也很明显,如数据一致...

    spring简单的缓存

    参考链接提供的CSDN博客文章《[Spring简单缓存实现](http://blog.csdn.net/maoyeqiu/article/details/50238035)》中,作者详细介绍了如何在Spring项目中实现缓存,包括配置、注解使用以及注意事项,是一个很好的学习...

    java Map实现的cache manager,定时清除缓存里面的值

    java Map实现的cache manager,定时清除缓存里面的值,使数据一致保持最新

    仿redis缓存Java版轻量级缓存组件LocalCache

    仿redis缓存Java版轻量级缓存组件LocalCache,基于JVM内存实现数据缓存及过期机制

    Java缓存技术的使用实例

    在Java中,我们通常使用两种类型的缓存:本地缓存(如Java集合框架中的HashMap)和分布式缓存(如Redis、Hazelcast或 Ehcache)。 本地缓存通常适用于小型应用或内存允许的情况,而分布式缓存在多服务器环境下更...

    带有本地缓存机制的http连接框架

    3. 内置缓存:内置了本地缓存机制,无需额外编写代码即可实现数据的本地存储和读取。 4. 支持多种请求方法:GET、POST、PUT、DELETE等HTTP方法都可轻松使用。 5. 请求参数与Header管理:方便地添加请求参数和自定义...

    Java本地缓存

    Java本地缓存是一种在应用程序内存中存储数据的技术,主要用于提高数据访问速度,减少对远程服务或数据库的依赖,从而提升应用性能。在处理服务间依赖关系时,本地缓存能够起到关键作用,尤其是在高并发环境下,它能...

    JAVA缓存技术深入了解

    1. **本地缓存**:如`java.util.concurrent.ConcurrentHashMap`,可以在单个线程或者多线程环境中提供快速的键值对存储。虽然简单,但在某些场景下已经足够使用。 2. **分布式缓存**:如`Hazelcast`、`Infinispan`...

    Java对象缓存系统的实现,实现了LRU算法,并可以进行集群同步

    5. `oscache-2.4.1.jar` 是一个开源的缓存框架,提供了本地缓存和分布式缓存功能,可能在这个项目中用于辅助实现LRU缓存。 6. `commons-logging-1.1.jar` 是Apache Commons Logging库,它是一个日志抽象层,允许在...

    springboot本地缓存(guava与caffeine).docx

    在本地缓存中,我们可以使用 Guava 或 Caffeine 等库来实现缓存机制。 1. 场景描述 在实际开发中,我们经常遇到需要频繁访问数据库或远程服务以获取数据的情况,这种情况下,使用本地缓存可以大大提高应用程序的...

    java 数据缓存

    Guava Cache提供了线程安全的本地缓存实现,支持自定义加载函数、过期时间、大小限制等特性。源码中,你可以看到它使用了Striped64来实现并发控制,以及WeakReference和SoftReference来管理内存占用。Guava Cache的...

    Java缓存Map设置过期时间实现解析

    LoadingCache是一个线程安全的本地缓存解决方案,提供缓存回收机制,监控缓存加载/命中情况,灵活强大的功能,简单易上手的API。 4. ExpiryMap实现原理: ExpiryMap是继承至HashMap,重写了所有对外的方法,对每个...

Global site tag (gtag.js) - Google Analytics