`
hougechuanqi
  • 浏览: 73449 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

本地缓存实现

 
阅读更多

public class LazyRemovalCache<K,V> {

/**

* 缓存对象的hashMap

*/

    private final ConcurrentMap<K,Entry<V>> map=new ConcurrentHashMap<K,Entry<V>>();

 

    /** Max number of elements, if exceeded, we remove all elements marked as removable and older than max_age ms

     * 缓存允许的最大条目

     *  */

    private final int max_elements;

 

    /**

     * 缓存对象的最大生命周期

     */

    private final long max_age;

 

 

    /**

     * 打印函数接口

     * @author Administrator

     *

     * @param <K>

     * @param <V>

     */

    public interface Printable<K,V> {

        String print(K key,V val);

    }

 

 

    /**

     * 无参构造函数

     */

    public LazyRemovalCache() {

        this(200, 5000L);

    }

 

    /**

     * 带参数的构造函数

     * @param max_elements

     * @param max_age

     */

    public LazyRemovalCache(int max_elements, long max_age) {

        this.max_elements=max_elements;

        this.max_age=max_age;

    }

 

    /**

     * 缓存中添加缓存对象

     * @param key

     * @param val

     */

    public void add(K key, V val) {

        if(key != null && val != null)

            map.put(key, new Entry<V>(val)); // overwrite existing element (new timestamp, and possible removable mark erased)

        checkMaxSizeExceeded();

    }

 

    /**

     * 得到一个缓存对象

     * @param key

     * @return

     */

    public V get(K key) {

        if(key == null)

            return null;

        Entry<V> entry=map.get(key);

        return entry != null? entry.val : null;

    }

 

    /**

     * 根据缓存对象得到缓存KEY值

     * @param val

     * @return

     */

    public K getByValue(V val) {

        if(val == null) return null;

        for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {

            Entry<V> v=entry.getValue();

            if(v.val != null && v.val.equals(val))

                return entry.getKey();

        }

        return null;

    }

 

    /**

     * 删除一个缓存对象

     * @param key

     */

    public void remove(K key) {

        remove(key, false);

    }

 

    /**

     * 删除缓存对象

     * @param key

     * @param force true:强制删除,false:非强制删除

     */

    public void remove(K key, boolean force) {

        if(key == null)

            return;

        if(force)

            map.remove(key);

        else {

            Entry<V> entry=map.get(key);

            if(entry != null)

                entry.removable=true;

        }

        checkMaxSizeExceeded();

    }

 

    /**

     * 删除一个集合的缓存的key值

     * @param keys

     */

    public void removeAll(Collection<K> keys) {

        removeAll(keys, false);

    }

 

    public void removeAll(Collection<K> keys, boolean force) {

        if(keys == null || keys.isEmpty())

            return;

        if(force)

            map.keySet().removeAll(keys);

        else {

            for(K key: keys) {

                Entry<V> entry=map.get(key);

                if(entry != null)

                    entry.removable=true;

            }

        }

        checkMaxSizeExceeded();

    }

 

    /**

     * 清空缓存对象

     * @param force true:强制清空,false:非强制清空

     */

    public void clear(boolean force) {

        if(force)

            map.clear();

        else {

            for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {

                Entry<V> val=entry.getValue();

                if(val != null) {

                    Entry<V> tmp=entry.getValue();

                    if(tmp != null)

                        tmp.removable=true;

                }

            }

        }

    }

 

    public void retainAll(Collection<K> keys) {

        retainAll(keys, false);

    }

 

    /**

     * 移除交集的key值

     * @param keys

     * @param force

     */

    public void retainAll(Collection<K> keys, boolean force) {

        if(keys == null || keys.isEmpty())

            return;

        if(force)

            map.keySet().retainAll(keys);

        else {

            for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {

                if(!keys.contains(entry.getKey())) {

                    Entry<V> val=entry.getValue();

                    if(val != null)

                        val.removable=true;

                }

            }

        }

        checkMaxSizeExceeded();

    }

 

    /**

     * 得到Key值set数组

     * @return

     */

    public Set<V> values() {

        Set<V> retval=new HashSet<V>();

        for(Entry<V> entry: map.values()) {

            retval.add(entry.val);

        }

        return retval;

    }

 

    /**

     * 得到缓存的内容

     * @return

     */

    public Map<K,V > contents() {

        Map<K,V> retval=new HashMap<K,V>();

        for(Map.Entry<K,Entry<V>> entry: map.entrySet())

            retval.put(entry.getKey(), entry.getValue().val);

        return retval;

    }

 

    public int size() {

        return map.size();

    }

 

    public String printCache() {

        StringBuilder sb=new StringBuilder();

        for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {

            sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");

        }

        return sb.toString();

    }

 

    public String printCache(Printable print_function) {

        StringBuilder sb=new StringBuilder();

        for(Map.Entry<K,Entry<V>> entry: map.entrySet()) {

            K key=entry.getKey();

            V val=entry.getValue().val;

            sb.append(print_function.print(key, val));

        }

        return sb.toString();

    }

 

    public String toString() {

        return printCache();

    }

 

 

    private void checkMaxSizeExceeded() {

        if(map.size() > max_elements) {

            removeMarkedElements();

        }

    }

 

    /**

     * Removes elements marked as removable

     * 删除掉被标志删除的元素

     * 

     */

    public void removeMarkedElements() {

        long curr_time=System.currentTimeMillis();

        for(Iterator<Map.Entry<K,Entry<V>>> it=map.entrySet().iterator(); it.hasNext();) {

            Map.Entry<K, Entry<V>> entry=it.next();

            Entry<V> tmp=entry.getValue();

            if(tmp.removable && (curr_time - tmp.timestamp) >= max_age) {

                it.remove();

            }

        }

    }

 

 

    /**

     * 

     * @author 缓存条目的封装类

     *

     * @param <V>

     */

    private static class Entry<V> {

    /**

    * 缓存的对象

    */

        private final V val;

        /**

         * 时间戳

         */

        private final long timestamp=System.currentTimeMillis();

        /**

         * 是否被移除的标志

         */

        private boolean removable=false;

 

        public Entry(V val) {

            this.val=val;

        }

 

        public String toString() {

            return val + " (" + (System.currentTimeMillis() - timestamp) + "ms old" + (removable? ", removable" : "") + ")";

        }

    }

}

分享到:
评论
1 楼 yugaochao 2015-11-27  
这个怎么使用呢

相关推荐

    Java利用ConcurrentHashMap实现本地缓存demo

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

    spring简单的缓存

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

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

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

    微信小程序基于本地缓存实现点赞功能的方法

    本文实例讲述了微信小程序基于本地缓存实现点赞功能的方法。分享给大家供大家参考,具体如下: wxml中的写法 注意: 1. 使用wx:if={{condition}} wx:else实现图标的切换效果; 2. 为图片绑定点击事件bindtap=to...

    redis本地缓存与redis缓存

    在“redis本地缓存与redis缓存”的主题中,我们将深入探讨这两种缓存方式及其各自的特点。 首先,我们要理解什么是本地缓存。本地缓存指的是将数据存储在应用程序的内存中,通常是Java的HashMap、Guava Cache或C#的...

    Java本地缓存的实现代码

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

    kotlin-cache:本地缓存实现

    Kotlin缓存Kotlin中的缓存实现可以在代码中本地使用。 这个想法是要消除开发人员为每个项目创建的恒定缓存。 当前实现:永久性快取永久缓存是一个简单的缓存,它将无限期保存该值。用法val cache = PermanentCache ...

    缓存、缓存算法和缓存框架简介.docx

    4. **Guava Cache**:Google Guava 库的一部分,提供了一个简单的本地缓存实现,适用于Java应用程序。 5. **Hazelcast**:一个开源的内存数据网格,提供分布式缓存、Map、Queue、Topic等功能。 缓存框架的选择应...

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

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

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

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

    JS localStorage实现本地缓存的方法

    可以通过检查`window.localStorage`是否存在来实现。如果该对象存在,说明浏览器支持localStorage。 ```javascript if (typeof(Storage) !== "undefined") { // 支持localStorage } else { // 不支持localStorage...

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

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

    android本地缓存

    本篇文章将详细介绍Android本地缓存的基本概念、实现方式,以及如何使用`AsimpleCacheDemo`进行实践。 **本地缓存的基本概念** 本地缓存可以分为内存缓存和磁盘缓存。内存缓存通常使用`WeakReference`或`...

    Java两级缓存框架,让应用支持两级缓存框架ehcache+redis 避免完全使用独立缓存系统所带来的网络IO开销问题

    在新的版本中,Ehcache 引入了 Caffeine 库作为其默认的本地缓存实现。Caffeine 是一个高性能、低延迟的本地缓存,它利用了现代多核处理器的特性,提供了出色的并发性能。一级缓存位于应用程序服务器内部,数据读取...

    延时加载+静态资源本地缓存

    "延时加载+静态资源本地缓存"是两种非常有效的技术手段,它们能够帮助我们实现这一目标。本篇文章将详细探讨这两种策略,以及如何将它们应用于实际项目中。 首先,让我们来看看静态资源本地缓存。静态资源通常包括...

    MAC版本outlook本地缓存路径

    ### MAC版本Outlook本地缓存路径详解 #### 一、Outlook for Mac 介绍 Microsoft Outlook for Mac 是一款由微软公司开发的专业电子邮件客户端与个人信息管理软件,它为Mac用户提供了与Windows版本相媲美的功能体验...

    远景本地缓存iscsicache

    这个文件名"iscsicache.exe"很可能是一个执行文件,它是实现"远景本地缓存iscsicache"功能的软件组件。这可能是一个服务或驱动程序,负责管理和优化iSCSI连接的本地缓存操作。当这个程序运行时,它会监控iSCSI会话,...

    java 数据缓存

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

Global site tag (gtag.js) - Google Analytics