Java 缓存机制

缓存主要可分为二大类:

一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;

二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import net.blogjava.frankiegao123.log.slf4j.Log;
import net.blogjava.frankiegao123.log.slf4j.LogFactory;

/**
 * <p>System.Config 配置缓存</p>
 *
 * @author frankiegao123
 * 2010-6-10 下午02:48:35
 */
@Component("configCache")
public class ConfigCache implements ConfigService {

    private final static Log log = LogFactory.getLog(ConfigCache.class);

    /**
     * 更新缓存时记录的时间
     */
    private volatile long time = 0L;

    /**
     * 正在更新缓存时的门闩,为 true 时表示当前没有更新缓存,为 true 时表示当前正在更新缓存
     */
    private volatile boolean updateGate = true;

    /**
     * 缓存容器
     */
    private Map<String, SysConfig> cache = new ConcurrentHashMap<String, SysConfig>();

    private CommonDao commonDao;

    @Autowired
    public ConfigCache(CommonDao commonDao) {
        this.commonDao = commonDao;
        log.info("initializing cache...");
        refreshCache();
        time = System.currentTimeMillis();
        log.info("initialized cache finished, cache size: {}, set cache time to current: {}, cache timeout: {}ms", cache.size(), time, ConfigConstant.CACHE_TIMEOUT);
    }

    /**
     * <p>根据配置的键名获取配置值</p>
     *
     * @param configKey
     * @return
     * @author frankiegao123
     * 2010-6-10 上午11:18:33
     */
    public SysConfig getSysConfig(String configKey) {
        long current = System.currentTimeMillis();
        if(updateGate && isTimeout(current)) {
            synchronized (this) {
                if(updateGate) {
                    timeoutSynRefresh(current);
                }
            }
        }
        return cache.get(configKey);
    }

    /**
     * <p>超时时更新缓存。该方法需要在同步环境中调用</p>
     * @param current
     * @author frankiegao123
     * 2010-6-10 上午11:16:30
     */
    private void timeoutSynRefresh(long current) {
        updateGate = false;
        log.info("refresh cache start..., time out: {}, size: {}, set updateGate to false", (current - time) / 1000.0, cache.size());
        try {
            refreshCache();
            time = current;
            log.info("refresh cache finished, size after update: {}, set cache time to current: {}", cache.size(), String.valueOf(time));
        } catch (Exception e) {
            log.error("refresh cache failed", e);
        } finally {
            updateGate = true;
            log.info("refresh cache finished, set updateGate to true");
        }
    }

    /**
     * <p>更新缓存数据</p>
     *
     * @author frankiegao123
     * 2010-6-10 上午11:15:55
     */
    private void refreshCache() {
        List<SysConfig> configs = commonDao.getSysConfigs();
        for(Iterator<SysConfig> i = configs.iterator(); i.hasNext(); ) {
            SysConfig config = i.next();
            cache.put(config.getKey(), config);
        }
        commonDao.clear();
        SysConfig config = cache.get(SysConfig.TEST_KEY);
        if(config == null) {
            log.error("refresh cache, cannot find TEST_KEY");
        } else {
            log.info("refresh cache, find TEST_KEY = [{}]", config.getValue());
        }
    }

    /**
     * <p>缓存是否超时</p>
     *
     * @param current
     * @return
     * @author frankiegao123
     * 2010-6-10 上午11:16:12
     */
    private boolean isTimeout(long current) {
        return (current - time >= ConfigConstant.CACHE_TIMEOUT);
    }

    Collection<SysConfig> getSysConfigs() {
        return Collections.unmodifiableCollection(cache.values());
    }

    int getSize() {
        return cache.size();
    }

    long getTime() {
        return time;
    }

    boolean isUpdateGate() {
        return updateGate;
    }

    void refresh() {
        time = 0L;
        log.info("refresh: reset cache time to 0");
        getSysConfig("none");
        log.info("refresh: refresh cache finished, cache: {0}", String.valueOf(time));
    }
}
时间: 2024-11-04 05:06:08

Java 缓存机制的相关文章

java缓存机制(上) map和spring注解@Cacheable

借鉴于   https://www.cnblogs.com/ms-grf/p/7249220.html 缓存的目的在于节省访问时间以及减轻大并发量访问带来资源上的消耗. 一.外存 除计算机内存和CPU缓存以外的存储器,如常见的C.D.E.F盘,还有U盘,软盘,硬盘,光盘之类.断电后仍能保存数据的完整性. 二.内存 用于与CPU沟通.计算机中所有程序的进行都是在内存中进行,CPU中所有的运算数据以及和外存之间交换的数据都存储在其中.数据断电不保存. 三.高速缓冲 一般情况下,CPU的处理数据速度非

Map实现java缓存机制的简单实例

缓存是Java中主要的内容,主要目的是缓解项目访问数据库的压力以及提升访问数据的效率,以下是通过Map实现java缓存的功能,并没有用cache相关框架. 一.缓存管理类 CacheMgr.java package com.henu.util; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; imp

java框架篇---hibernate之缓存机制

一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 二.what(Hibernate缓存原理是怎样的?)Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存. 1.Hibernate一级缓存又称为“Session的

Java 日志缓存机制的实现--转载

概述 日志技术为产品的质量和服务提供了重要的支撑.JDK 在 1.4 版本以后加入了日志机制,为 Java 开发人员提供了便利.但这种日志机制是基于静态日志级别的,也就是在程序运行前就需设定下来要打印的日志级别,这样就会带来一些不便. 在 JDK 提供的日志功能中,日志级别被细化为 9 级,用以区分不同日志的用途,用来记录一个错误,或者记录正常运行的信息,又或是记录详细的调试信息.由于日志级别是静态的,如果日志级别设定过高,低级别的日志难以打印出来,从而导致在错误发生时候,难以去追踪错误的发生原

Java三大框架之——Hibernate中的三种数据持久状态和缓存机制

Hibernate中的三种状态   瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过Session持久化操作,缓存中存在这个对象的数据为持久状态并且数据库中存在这个对象对应的数据为持久状态这个时候有OID. 游离状态:当Session关闭,缓存中不存在这个对象数据而数据库中有这个对象的数据并且有OID为游离状态. 注:OID为了在系统中能够找到所需对象,我们需要为每一个对象分配一个

Java交换值及中间缓存机制

 实现交换int a,b的值的函数,C++可以采用引用或指针传递的方法,当Java不行: 因为Java的参数传递机制与C++不同(http://blog.csdn.net/woliuyunyicai/article/details/44096043), 如下方法均不能够实现: public void swap(int x, int y) { int temp = x; x = y; y = x; } public void swap(Integer x, Integer y) { Integ

Java中整型的缓存机制

译文出处: 张洪亮   原文出处:Java Papers 本文将介绍Java中Integer的缓存相关知识.这是在Java 5中引入的一个有助于节省内存.提高性能的功能.首先看一个使用Integer的示例代码,从中学习其缓存行为.接着我们将为什么这么实现以及他到底是如何实现的.你能猜出下面的Java程序的输出结果吗.如果你的结果和真正结果不一样,那么你就要好好看看本文了. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 pa

Java包装类中的缓存机制

本文将介绍Java中Integer的缓存相关知识.这是在Java 5中引入的一个有助于节省内存,提高性能的功能.首先看一个使用Integer的示例代码,从中学习其缓存行为.接着我们将为为什么这么实现以及他到底是如何实现的.你能猜出下面的的Java程序的输出结果吗.如果你的结果和真正结果不一样,那么你就要好好看看本文了. package com.javapapers.java; public class JavaIntegerCache { public static void main(Stri

如何利用缓存机制实现JAVA类反射性能提升30倍

一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> 分享者:宜信支付结算部支付研发团队高级工程师陶红 原文首发于宜信支付结算技术团队公号:野指针 在实际工作中的一些特定应用场景下,JAVA类反射是经常用到.必不可少的技术,在项目研发过程中,我们也遇到了不得不运用JAVA类反射技术的业务需求,并且不可避免地面临这个技术固有的性能瓶颈问题. 通过近两年的研究.尝