Java中常用缓存Cache机制的实现

图片 2

所谓缓存,正是将次第或种类有的时候要调用的目的存在内部存款和储蓄器中,叁次其利用时方可连忙调用,不必再去成立新的再次的实例。那样做能够减去系统开荒,提升系统功效。

目录:

图片 1

一:什么是缓存

缓存首要可分为二大类:

二:为啥要用本地缓存

一、通过文件缓存,看名就会知道意思文件缓存是指把数据存款和储蓄在磁盘上,不管您是以XML格式,类别化文件DAT格式依然其余文件格式;

三:我们一伊始是怎么施行地点缓存的

二、内部存款和储蓄器缓存,也便是贯彻二个类中静态Map,对那几个Map进行例行的增加和删除查.

四:Java本地缓存规范

代码如下 :

五:Java开源缓存框架

package lhm.hcy.guge.frameset.cache; 

import java.util.*; 

 //Description: 管理缓存 

 //可扩展的功能:当chche到内存溢出时必须清除掉最早期的一些缓存对象,这就要求对每个缓存对象保存创建时间 

public class CacheManager { 
    private static HashMap cacheMap = new HashMap(); 

    //单实例构造方法 
    private CacheManager() { 
        super(); 
    } 
    //获取布尔值的缓存 
    public static boolean getSimpleFlag(String key){ 
        try{ 
            return (Boolean) cacheMap.get(key); 
        }catch(NullPointerException e){ 
            return false; 
        } 
    } 
    public static long getServerStartdt(String key){ 
        try { 
            return (Long)cacheMap.get(key); 
        } catch (Exception ex) { 
            return 0; 
        } 
    } 
    //设置布尔值的缓存 
    public synchronized static boolean setSimpleFlag(String key,boolean flag){ 
        if (flag && getSimpleFlag(key)) {//假如为真不允许被覆盖 
            return false; 
        }else{ 
            cacheMap.put(key, flag); 
            return true; 
        } 
    } 
    public synchronized static boolean setSimpleFlag(String key,long serverbegrundt){ 
        if (cacheMap.get(key) == null) { 
            cacheMap.put(key,serverbegrundt); 
            return true; 
        }else{ 
            return false; 
        } 
    } 

    //得到缓存。同步静态方法 
    private synchronized static Cache getCache(String key) { 
        return (Cache) cacheMap.get(key); 
    } 

    //判断是否存在一个缓存 
    private synchronized static boolean hasCache(String key) { 
        return cacheMap.containsKey(key); 
    } 

    //清除所有缓存 
    public synchronized static void clearAll() { 
        cacheMap.clear(); 
    } 

    //清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配 
    public synchronized static void clearAll(String type) { 
        Iterator i = cacheMap.entrySet().iterator(); 
        String key; 
        ArrayList arr = new ArrayList(); 
        try { 
            while (i.hasNext()) { 
                java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); 
                key = (String) entry.getKey(); 
                if (key.startsWith(type)) { //如果匹配则删除掉 
                    arr.add(key); 
                } 
            } 
            for (int k = 0; k < arr.size(); k++) { 
                clearOnly(arr.get(k)); 
            } 
        } catch (Exception ex) { 
            ex.printStackTrace(); 
        } 
    } 

    //清除指定的缓存 
    public synchronized static void clearOnly(String key) { 
        cacheMap.remove(key); 
    } 

    //载入缓存 
    public synchronized static void putCache(String key, Cache obj) { 
        cacheMap.put(key, obj); 
    } 

    //获取缓存信息 
    public static Cache getCacheInfo(String key) { 

        if (hasCache(key)) { 
            Cache cache = getCache(key); 
            if (cacheExpired(cache)) { //调用判断是否终止方法 
                cache.setExpired(true); 
            } 
            return cache; 
        }else 
            return null; 
    } 

    //载入缓存信息 
    public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) { 
        Cache cache = new Cache(); 
        cache.setKey(key); 
        cache.setTimeOut(dt + System.currentTimeMillis()); //设置多久后更新缓存 
        cache.setValue(obj); 
        cache.setExpired(expired); //缓存默认载入时,终止状态为FALSE 
        cacheMap.put(key, cache); 
    } 
    //重写载入缓存信息方法 
    public static void putCacheInfo(String key,Cache obj,long dt){ 
        Cache cache = new Cache(); 
        cache.setKey(key); 
        cache.setTimeOut(dt+System.currentTimeMillis()); 
        cache.setValue(obj); 
        cache.setExpired(false); 
        cacheMap.put(key,cache); 
    } 

    //判断缓存是否终止 
    public static boolean cacheExpired(Cache cache) { 
        if (null == cache) { //传入的缓存不存在 
            return false; 
        } 
        long nowDt = System.currentTimeMillis(); //系统当前的毫秒数 
        long cacheDt = cache.getTimeOut(); //缓存内的过期毫秒数 
        if (cacheDt <= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE 
            return false; 
        } else { //大于过期时间 即过期 
            return true; 
        } 
    } 

    //获取缓存中的大小 
    public static int getCacheSize() { 
        return cacheMap.size(); 
    } 

    //获取指定的类型的大小 
    public static int getCacheSize(String type) { 
        int k = 0; 
        Iterator i = cacheMap.entrySet().iterator(); 
        String key; 
        try { 
            while (i.hasNext()) { 
                java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); 
                key = (String) entry.getKey(); 
                if (key.indexOf(type) != -1) { //如果匹配则删除掉 
                    k++; 
                } 
            } 
        } catch (Exception ex) { 
            ex.printStackTrace(); 
        } 

        return k; 
    } 

    //获取缓存对象中的所有键值名称 
    public static ArrayList getCacheAllkey() { 
        ArrayList a = new ArrayList(); 
        try { 
            Iterator i = cacheMap.entrySet().iterator(); 
            while (i.hasNext()) { 
                java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); 
                a.add((String) entry.getKey()); 
            } 
        } catch (Exception ex) {} finally { 
            return a; 
        } 
    } 

    //获取缓存对象中指定类型 的键值名称 
    public static ArrayList getCacheListkey(String type) { 
        ArrayList a = new ArrayList(); 
        String key; 
        try { 
            Iterator i = cacheMap.entrySet().iterator(); 
            while (i.hasNext()) { 
                java.util.Map.Entry entry = (java.util.Map.Entry) i.next(); 
                key = (String) entry.getKey(); 
                if (key.indexOf(type) != -1) { 
                    a.add(key); 
                } 
            } 
        } catch (Exception ex) {} finally { 
            return a; 
        } 
    } 

} 

package lhm.hcy.guge.frameset.cache; 

public class Cache { 
        private String key;//缓存ID 
        private Object value;//缓存数据 
        private long timeOut;//更新时间 
        private boolean expired; //是否终止 
        public Cache() { 
                super(); 
        } 

        public Cache(String key, Object value, long timeOut, boolean expired) { 
                this.key = key; 
                this.value = value; 
                this.timeOut = timeOut; 
                this.expired = expired; 
        } 

        public String getKey() { 
                return key; 
        } 

        public long getTimeOut() { 
                return timeOut; 
        } 

        public Object getValue() { 
                return value; 
        } 

        public void setKey(String string) { 
                key = string; 
        } 

        public void setTimeOut(long l) { 
                timeOut = l; 
        } 

        public void setValue(Object object) { 
                value = object; 
        } 

        public boolean isExpired() { 
                return expired; 
        } 

        public void setExpired(boolean b) { 
                expired = b; 
        } 
} 

//测试类, 
class Test { 
    public static void main(String[] args) { 
        System.out.println(CacheManager.getSimpleFlag("alksd")); 
//        CacheManager.putCache("abc", new Cache()); 
//        CacheManager.putCache("def", new Cache()); 
//        CacheManager.putCache("ccc", new Cache()); 
//        CacheManager.clearOnly(""); 
//        Cache c = new Cache(); 
//        for (int i = 0; i < 10; i++) { 
//            CacheManager.putCache("" + i, c); 
//        } 
//        CacheManager.putCache("aaaaaaaa", c); 
//        CacheManager.putCache("abchcy;alskd", c); 
//        CacheManager.putCache("cccccccc", c); 
//        CacheManager.putCache("abcoqiwhcy", c); 
//        System.out.println("删除前的大小:"+CacheManager.getCacheSize()); 
//        CacheManager.getCacheAllkey(); 
//        CacheManager.clearAll("aaaa"); 
//        System.out.println("删除后的大小:"+CacheManager.getCacheSize()); 
//        CacheManager.getCacheAllkey(); 

    } 
}

六:再一次贯彻地点缓存

所谓缓存,正是将顺序或系统时常要调用的靶子存在内部存款和储蓄器中,叁遍其采用时能够长足调用,不必再去成立新的双重的实例。那样做能够减弱系统开采,提升系统功效。

缓存首要可分为二大类:

1:通过文件缓存,从名称想到所包含的意义文件缓存是指把多少存款和储蓄在磁盘上,不管你是以XML格式,类别化文件DAT格式依旧其他文件格式;

2:内部存款和储蓄器缓存,也正是创设一个静态内部存款和储蓄器区域,将数据存款和储蓄进去,举个例子大家B/S结构的将数据存款和储蓄在Application中或许存款和储蓄在七个静态Map中。

在系统中,有些数据,数据量小,可是访谈十一分频仍(比方国标行政区域数据依旧部分数额词典等),针对这种情景,必要将数据搞到利用的地头缓存中,以晋级系统的会见功效,裁减无谓的数据库访问(数据库访问占用数据库连接,同一时间网络消耗超大),但是有一点亟需注意,正是缓存的攻陷空间以至缓存的失灵战略。

所谓的当地缓存是相对于网络来说的(包蕴集群,数据库访谈等)

重重境况的多寡,相当多是事情非亲非故的(CodeMaster,数据词典等)数据缓存,未有要求搞遍布式的集群缓存,再加上布满式缓存的营造,集群维护资金相比较高,不太相符这种状态数据。

这里介绍一下缓存使用的四个级次(摘自info布局师襄书档案)

图片 2缓存使用的两个级次

三:大家一齐初是怎么实践地点缓存的

public class CacheManager {

//二个地面包车型大巴缓存Map

private Map localCacheStore =new HashMap();

//贰个个体的对象,非懒汉方式

private static CacheManager cacheManager =new CacheManager();

//私有布局方法,外界不可以new八个对象

private CacheManager(){

}

//静态方法,外界获得实例对象

public static CacheManager getInstance(){

return cacheManager;

}

//获得缓存中的数据

public Object getValueByKey(String key){

return localCacheStore.get;

}

//向缓存中添增添少

public void putValue(String key ,Object value){

localCacheStore.put(key, value);

}

}

那是二个优越的单例情势,里面有个Map的变量来存储对象。

这段代码有何样难点吗?

一起未有,只是局限性很强。

四:Java当地缓存标准

Java缓存新典型(javax.cache),那几个专门的学业由JSXC60107所建议,已经被含有在Java
EE7中。

特性:

1.原子操作,跟java.util.ConcurrentMap雷同

2.从缓存中读取

3.写入缓存

4.缓存风云监听器

5.数额总结

6.分包全体隔断(ioslation)等级的作业

7.缓存注脚(annotations)

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

9.援用保存和值保存定义

就算那么些今后利用不是很宽泛,不过大家使用过Spring
Boot的时候,大家应该发现Spring
Boot的Cache已经上马在向这么些趋势扩充贴近了。超多也在应用了。

对此上述的性状,我们看看以前我们得以达成的这段代码有何难题啊?

1、 未有缓存大小的装置,不可能界定缓存体的轻重甚至存款和储蓄数据的约束(max size
limit);

2、 未有缓存的失灵攻略(eviction policies);

3、 未有弱键援用,在内部存储器占用吃紧的图景下,JVM是回天乏术回笼的(weak
rererences keys);

4、 未有监察和控制总结(statistics);

5、 长久性存款和储蓄(persistent store)

五:Java开源缓存框架

正如显赫的本地缓存开源框架有:

1.OSCache

OSCache有以下特点:缓存任何对象,你能够不受约束的缓存部分jsp页面或HTTP乞求,任何java对象都足以缓存。具有康健的API–OSCache
API给你到家的次序来决定全数的OSCache天性。恒久缓存–缓存能自由的写入硬盘,因而同意高昂的创导(expensive-to-create卡塔尔(قطر‎数据来保证缓存,以致能让动用重启。接济集群–集群缓存数据能被单个的拓宽参数配置,无需更正代码。缓存记录的晚点–你能够有最大限度的决定缓存对象的超时,蕴含可插入式的刷新计策(若是暗许品质无需时卡塔尔。

2.JCache

Java缓存新专门的工作(javax.cache)

3.cache4j

cache4j是一个有大约API与实现高效的Java对象缓存。它的风味包蕴:在内部存款和储蓄器中开展缓存,设计用来多线程意况,三种达成:同步与拥塞,各类缓存撤消计谋:LFU,
LRU, FIFO,可利用强援用。

4.ShiftOne

ShiftOneJavaObject Cache是四个执行一多级严厉的对象缓存计谋的Java
lib,如同二个轻量级的配备缓存专门的学问景况的框架。

5.WhirlyCache

Whirlycache是一个快速的、可安排的、存在于内部存款和储蓄器中的对象的缓存。

6.Guava Cache

Guava Cache是三个全内部存储器的本地缓存实现,它提供了线程安全的兑现机制。

推荐几个布满式缓存框架:

1:Ehcache

Ehcache是一个Java达成的开源布满式缓存框架,EhCache
能够使得地缓解数据库的载荷,能够让数据保存在不一致服务器的内部存款和储蓄器中,在供给多少的时候能够异常快存取。同期EhCache
扩展极其简单,官方提供的Cache配置情势有少数种。你能够透过注脚配置、在xml中布署、在前后相继里陈设或许调用布局方法时传出不一致的参数。

2:Cacheonix– 高品质Java布满式缓存系统

Cacheonix相符也是多少个基于Java的布满式集群缓存系统,它雷同能够协理你兑现布满式缓存的布局。

3:JBoss Cache– 基于事物的Java缓存框架

JBoss
Cache是一款基于Java的事务管理缓存系统,它的靶子是构建二个以Java框架为根底的集群实施方案,能够是服务器应用,也能够是Java
SE应用。

4:Voldemort– 基于键-值(key-value)的缓存框架

Voldemort是一款基于Java开辟的分布式键-值缓存系统,像JBoss
Cache相仿,Voldemort相仿扶植多台服务器之间的缓存同步,以增加系统的可信性和读取品质。

5:Redis

Redis是借助内部存款和储蓄器、可持久化的日志型、Key-Value数据库高质量存款和储蓄系统,并提供各类语言的API.

6:memcached

memcached是行使最广的开源cache产物,它自个儿不提供布满式的解决方案,作者猜测一方面它想尽量保持成品轻便便捷,另一面cache的key-value的特点使得让memcached布满式起来比较轻便。memcached的分布式爱戴在于顾客端,通过客商端的路由管理来搭建memcached集群情状,由此在服务端,memcached集群情况实际上正是多个个memcached服务器的堆叠品,情形的搭建比较简单。下边从客商端做路由和服务端集群景况搭建两地方来谈怎么样让memcached遍布式

六:再一次兑现本地缓存

哈哈,你们受骗了,等后天吧?

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图