java缓存机制怎么写?
需求:由于对数据库的操作比较频繁,所以考虑把常用的数据以及对数据操作比较频繁的数据(XML格式)放在内存中或缓存中,放在内存中数据当服务器重启时候,把这些数据初化在内存上;放在缓存中的数据在数据库中的数据有所变动的时候,用户访问的时候会做判断,让其从数据库中读取数据而不是从缓存中,然后把读出来的数据同时存在内存和缓存中。
补充:不用其它技术以及框架,存java代码。
希望高手们给点指点,最好发个例子过来瞄瞄!!!(在线等待中。。。。)
[解决办法]
缓存其实就好比一个static变量一样,不要想的太难了,比如说你定义了一个List,这个list里面放了5个数据,这就相当于是一个缓存,还有session,这些都是缓存。java代码你就自个写吧,缓存的性能怎么样就看你自己写的代码的质量了。
1、肯定有对文件操作的
2、肯定会使用线程的
[解决办法]
写个servlet在启动的时候初始化load到内存。有变动的时候去刷新一下内存。
[解决办法]
我自己封装过一个,不知道楼主用得上不
大概是 :用 hashMap 来保存的 结合 Cache
hashMap 键 用来保存别名 ,value 用来可以放任何东西 ,下次查询 可以直接 从 Cache 直接获取 呵呵
[解决办法]
原来有这么多方法的呀!
[解决办法]
关注中。。帮顶
[解决办法]
可以考虑利用singleton模式来编写缓存类,这样类的实例在数据不发生变化的情况下只被初始化一次,效率很高,可以在类里边定义很多其他的private static class来封装想要缓存的数据,当某些数据发生变化时,可以将singleton实例reset成null,这样就会重新load数据到各个static class中了。
[解决办法]
EhCache 很方便
[解决办法]
自己写的话,只能用在内存策略中,下面这代码我已经在好几个项目中应用过了,至今为止还未出现不正确的情况。
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)); }}
[解决办法]
读取时先从缓存读取,如果缓存中没有,从数据库中读取,同时把读取到的数据更新到缓存中。
当修改时,修改数据库中的内容,同时更新缓存。
[解决办法]
上面这代码的运行机制是这样的:
1:设定超时时间,当某一请求来到时缓存超过限定时间时,重新刷新缓存。没有请求来时,即便超时了也不会去主动刷新,待下一个请求来就会刷新了。
2:在刷新缓存的过程中,若有其他请求来时,这些请求继续使用旧的数据。(这一点之前考虑了很久,最后确定为这一方案,否则有一个在刷新缓存时会阻塞很多的线程。)
[解决办法]
可以用hibbernate实现缓存
[解决办法]
想做内存数据库?
楼主想不依赖框架自己动手的思路是好的,但是现在业界的项目工期和功能需求都要求很高,你完全从头开始做,很多方面考虑得不如现有的开源框架成熟,且这些框架经过了很多项目的考验,功能已经很强大,集成到你自己的项目里也很方便
可以考虑luncene,索引方式的内存数据库
[解决办法]
学习了,帮顶
[解决办法]
学习了..