Java进程内缓存

今天和同事聊到了缓存,在Java中实现进程缓存。这里主要思想是,用一个map做缓存。缓存有个生存时间,过期就删除缓存。这里可以考虑两种删除策略,一种是起一个线程,定期删除过期的key。第二个是,剔除模式,比较懒,访问到某个key的时候才,才去检查这个key是否过期,过期删除。

首先,对要缓存的value做了层封装,带了个时间戳

/**
 * Created by gxf on 2017/6/28.
 */
public class ValueWithTimeStamp<V>{
    private long expireTime;
    private V value;

    public ValueWithTimeStamp(long expireTime, V value) {
        this.expireTime = expireTime;
        this.value = value;
    }

    public long getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(long expireTime) {
        this.expireTime = expireTime;
    }

    public V getValue() {
        return value;
    }

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

ok,起线程定期删除策略的模式

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by gxf on 2017/6/28.
 * 使用线程,定期删除过期的key
 */
public class CacheMap<K, V>  {
    //这里使用ConcurrentHashMap避免,clean的时候,主线程修改chache,造成异常,
    //使用ConcurrentHashMap可以控制并发修改cache
    private Map<K, ValueWithTimeStamp<V>> cache = new ConcurrentHashMap<K, ValueWithTimeStamp<V>>();
    private static boolean cleanTaskIsRunning = false;

    //ttl 过期时间 单位:秒
    public void put(K key, V value, int ttl){
        long expireTime = System.currentTimeMillis() + ttl * 1000;
        ValueWithTimeStamp<V> valueWithTimeStamp = new ValueWithTimeStamp<>(expireTime, value);
        cache.put(key, valueWithTimeStamp);
        if(!cleanTaskIsRunning){
            startCleanTask();
            cleanTaskIsRunning = !cleanTaskIsRunning;
        }
    }

    public V get(K key){
        ValueWithTimeStamp<V> valueWithTimeStamp = cache.get(key);
        return null == valueWithTimeStamp ? null : valueWithTimeStamp.getValue();
    }

    /**
     * 启动清理线程
     * */
    private void startCleanTask(){
        Thread cleanThread = new Thread(new CleanTask());
        cleanThread.start();
    }

    /**
     * 清理过期的key
     * */
    class CleanTask implements Runnable{
        public void run(){
            while(true){
                long currentTime =  System.currentTimeMillis();
                //遍历map
                for(Map.Entry<K, ValueWithTimeStamp<V>> entry : cache.entrySet()){
                    ValueWithTimeStamp<V> valueWithTimeStamp = entry.getValue();
                    long expireTime = valueWithTimeStamp.getExpireTime();
                    //过期时间到了
                    if(currentTime > expireTime){
                        System.out.println("key : " + entry.getKey() + " expired ");
                        cache.remove(entry.getKey());
                    } //if
                } //for
                //每隔1s扫描map对象
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } //while
        }
    }
}

注意,这里需要使用ConcurrentHashMap做缓存。不然会出现多线线程操作map对象的异常

第二种策略,剔除模式

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by 58 on 2017/6/28.
 * 这里使用懒惰模式,获取key的时候,才剔除过期的key
 */
public class CacheMap1<K, V> {
    private Map<K, ValueWithTimeStamp<V>> cache = new ConcurrentHashMap<K, ValueWithTimeStamp<V>>();

    public void put(K key, V value, int ttl){
        long expireTime = System.currentTimeMillis() + ttl * 1000;
        ValueWithTimeStamp<V> valueWithTimeStamp = new ValueWithTimeStamp<V>(expireTime, value);
        cache.put(key, valueWithTimeStamp);
    }

    public V get(K key){
        ValueWithTimeStamp<V> valueWithTimeStamp = cache.get(key);
        long expireTime = valueWithTimeStamp.getExpireTime();
        long currentTime = System.currentTimeMillis();
        //key已经过期,删除,返回null
        if(currentTime > expireTime){
            System.out.println("key :" + key + " is expired.");
            cache.remove(key);
            return null;
        }

        return cache.get(key).getValue();
    }
}

项目中用到了redis,用这种方式应该会更快,这两天优化一下代码

时间: 2024-10-16 16:01:42

Java进程内缓存的相关文章

Java的进程内缓存框架:EhCache (转)

EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. Ehcache缓存的特点: 1. 快速. 2. 简单. 3. 多种缓存策略 4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题 5. 缓存数据会在虚拟机重启的过程中写入磁盘 6. 可以通过RMI.可插入API等方式进行分布式缓存 7. 具有缓存和缓存管理器的侦听接口 8. 支持多缓存管理器实例,以及一个实例的多个缓存区域 9. 提供Hibernate的缓存实现 E

程序员修神之路--高并发下为什么更喜欢进程内缓存

菜菜哥,告诉你一个好消息 YY妹子,什么好消息,你有男票了? 不是啦,我做的一个网站,以前经常由于访问量太大而崩溃,现在我加上了缓存,很稳定啦 加的什么缓存呢? 我用的redis,号称业界最快的缓存组件了 你觉得现在的缓存操作应该是最快的了吗? 是的,我觉得没有缓存能比这种模式更快了 你先停停,我给你先讲个故事 进程内缓存是指缓存和应用程序在相同地址空间.即同一个进程内.分布式缓存是指缓存和应用程序位于不同进程的缓存,通常部署在不同服务器上. 从前有个机构,机构的主人叫做 CPU,这个机构专门派

Java的进程内缓存框架:EhCache

Ehcache缓存的特点: 1. 快速. 2. 简单. 3. 多种缓存策略 4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题 5. 缓存数据会在虚拟机重启的过程中写入磁盘 6. 可以通过RMI.可插入API等方式进行分布式缓存 7. 具有缓存和缓存管理器的侦听接口 8. 支持多缓存管理器实例,以及一个实例的多个缓存区域 9. 提供Hibernate的缓存实现 Ehcache缓存的使用(1) – 安装ehcache Ehcache 的特点,是一个纯Java ,过程中(也可以理解成插入式)缓存

java 整合redis缓存 SSM 后台框架 rest接口 shiro druid maven bootstrap html5

获取[下载地址]   QQ: 313596790A 调用摄像头拍照,自定义裁剪编辑头像 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单;  技术:313596790 freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块C 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Druid在监控.可扩

java 整合redis缓存 SSM 后台框架 rest接口 shiro druid

获取[下载地址]   QQ: 313596790   [免费支持更新] 三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体 [新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; QQ:313596790 freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块 B 集成阿里巴巴数据库连

java应用本地缓存

在java应用中,对于访问频率比较高,又不怎么变化的数据,常用的解决方案是把这些数据加入缓存.相比DB,缓存的读取效率快好不少.java应用缓存一般分两种,一是进程内缓存,就是使用java应用虚拟机内存的缓存:另一个是进程外缓存,现在我们常用的各种分布式缓存.相比较而言,进程内缓存比进程外缓存快很多,而且编码也简单:但是,进程内缓存的存储量有限,使用的是java应用虚拟机的内存,而且每个应用都要存储一份,有一定的资源浪费.进程外缓存相比进程内缓存,会慢些,但是,存储空间可以横向扩展,不受限制.

java 整合redis缓存 SSM 后台框架

A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Druid在监控.可扩展性.稳定性和性能方面都有明显的优势C 集成安全权限框架shiro ;  Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权,更安全,更可靠D

java 整合redis缓存 SSM 后台框架 rest接口 shiro

获取[下载地址]     [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.

java 整合redis缓存 SSM 后台框架 rest接口

获取[下载地址]   QQ: 313596790   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; QQ:313596790freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池dr