我这里说的cache不是指CPU和RAM之间的缓存,而是Java应用中间常用的缓存。最常使用的场合就是访问数据库的时候为了提高效率而使用的 cache。一般的用法就是把数据从数据库读到内存,然后之后的数据访问都从内存来读,从而减少对数据库的读取次数来提高效率。

在使用cache的时候最容易犯的错误就是cache涉及了业务逻辑。使用cache的原意是只是提高程序效率,而不应该干涉程序结果。按照cahce的定义,cache应该是对数据访问端透明 地工作。所以在使用cache的时候我们可以问一下自己:“我把cache拿掉后程序还能运行吗?” “cache拿掉前后程序运行的结果一直吗?”。如果答案是否,那您就得重新考虑您的cache方案。我自己就碰到过这样的bug:数据库的有个表里面都 是些配置信息,也就是说是些读访问远大于写访问 的数据。然后这些数据被理所应当地在程序里面做成内存 cache。问题是有个delete方法删除了一条数据,但是没有更新内存cache。所以读操作的客户代码还是能读到这条数据。问题的根本就是后台数据和cache不一致。

cache的容量一般相对后台数据量都比较有限。一旦cache满了就势必要选择最没用的数据从cache里面删除掉,为新数据腾出空间。这里就涉及 cahce算法cache algorithm或者叫替换算法。在java的cache产品中一般叫evict policy。下面我们来看一下常用的cache algorithm。

  • 最近最少使用算法 Least Recently Used (LRU):
 这个算法就是把最近一次使用时间离现在时间最远的数据删除掉。最直观的结构应该是List,采取的算法是:每次访问一个元素后把这个元素放在 List一端,这样一来最远使用的元素自然就被放到List的另一端。每次evict的时候就把那最远使用的元素remove掉。但是现实中常采用的数据 结构是HashMap + List。因为List太慢,List只能提供O(n)的算法,要使得它的add,remove和get的算法为O(1)就必须使用HashMap。最简 单的实现就是利用JDK自带的LinkedHashMap,你可以把它看作普通的HashMap之外,每个元素的key都用链表连接起来从而实现顺序结 构。LinkedHashMap默认的元素顺序是put的顺序,但是如果使用带参数的构造函数,那么LinkedHashMap会根据访问顺序来调整内部 顺序。 LinkedHashMap的get()方法除了返回元素之外还可以把被访问的元素放到链表的底端,这样一来每次顶端的元素就是remove的元素。

  • First In, First Out算法

这个比较直观,就是个Queue。但是还是为了保证O(1)的效率,还是要用LinkedHashMap。但是这次使用默认的无参数的构造函数,LinkedHashMap内部使用的是put的顺序。因此每次remove顶端即可。

  • 最近最多时用算法Most Recently Used (MRU)

这个算法和LRU是相反操作,所以没什么新鲜的东西。每次remove LinkedHashMap底端的元素就可以实现。

  • 使用次数最小算法 Least Frequently Used (LFU)

这 个算法的核心是每次访问元素的时候,这个元素的次数属性加1。所以每次remove操作就是次数属性最小的元素。这次没法用LinkedHashMap来 实现了,因为LinkedHashMap没有接受comparator参数的功能。有些程序是用LinkedList + HashMap来实现。这样add和get操作还是O(1),只是remove操作的时候先要排序然后再remove,最快也就是O(n*log n),譬如利用快速排序。或者干脆在remove的时候只是做查找最小元素的算法来除去访问次数最小的元素。

另外还有其他的cache算法,譬如按照元素自带的过期值expiration和随机random来evict元素的算法。在真正的cache产品中数据结构和算法要比上面描述的要复杂。有些产品自己定义一些数据结构来提高效率,毕竟cache是为了提高效率而产生的。高级的cache产品还可能包括事务机制,JMX和支持cluster环境这样复杂的特性。

 
   目前比较主流的cache产品有EHCache,OSCache,SwarmCache和JBoss Cache,很多使用Hibernate的人都对都此有些了解。关于JBoss Cache,它在将来可能被JBoss的另外一个叫infinispan 的数据网格平台项目所替代。

Java实现cache的基本机制的更多相关文章

  1. java整形中的缓存机制

      英文原文:Java Integer Cache 翻译地址:Java中整型的缓存机制 原文作者:Java Papers 翻译作者:Hollis 转载请注明出处. 本文将介绍Java中Integer的 ...

  2. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  3. 深入Java核心 Java中多态的实现机制(1)

    在疯狂java中,多态是这样解释的: 多态:相同类型的变量,调用同一个方法时,呈现出多中不同的行为特征, 这就是多态. 加上下面的解释:(多态四小类:强制的,重载的,参数的和包含的) 同时, 还用人这 ...

  4. Java 内存区域和GC机制分析

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  5. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

  6. java基础之 垃圾回收机制

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

  7. Java 内存区域和GC机制-java概念理解

    推荐几篇关于java内存介绍的文章 Java 内存区域和GC机制 http://www.cnblogs.com/hnrainll/archive/2013/11/06/3410042.html    ...

  8. Java内存区域和GC机制篇

    Java内存区域和GC机制一.目录 1.Java垃圾回收概括 2.Java内存区域 3.Java对象的访问方式 4.Java内存访问机制 5.Java GC 机制 6.Java垃圾收集器 二.Java ...

  9. JAVA混型和潜在类型机制

    一.混型 ①.定义 二.利用JAVA如何实现混型 ①.代理   ②.装饰器模式  ③.动态代理模式   ④.装饰器模式与代理模式的区别 三.潜在类型机制 ①.定义 四.JAVA的潜在类型机制的补偿 ① ...

随机推荐

  1. 四则运算2--c++

    1.设计思路: 上篇已写,不在解释..... 2.源代码: #include<iostream.h>#include<stdlib.h>#include "time. ...

  2. 微软Hololens学院教程-Hologram 220-空间声音(Spatial sound )【本文是老版本,与最新的微软教程有出入】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦! 原文链接https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  3. jsp或Action获取请求参数中文乱码

    普通情况下,中文字符会被自动转换成iso-8859-1的编码格式通过网络传输,而这种格式是没办法直接表示出我们认识的中文字符的,所以还要手动将他转换回之前的字符集. 一般在servlet或者actio ...

  4. JavaScript 闭包详解

    一.Javascript闭包的用途 事实上,通过使用闭包,我们可以做很多事情.比如模拟面向对象的代码风格:更优雅,更简洁的表达出代码:在某些方面提升代码的执行效率. 1.匿名自执行函数 我们知道所有的 ...

  5. CocoaPods最佳实践探讨

    近期在项目中首次使用了CocoaPods.从软件工程的角度来看,我对目前常见的CocoaPods使用方法有些意见,建议做一些改进.先说一下我建议的最佳实践,后面再分析为什么要这样做.并且希望大家根据自 ...

  6. HDU 5647 DZY Loves Connecting 树形dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5647 题解: 令dp[u][0]表示u所在的子树中所有的包含i的集合数,设u的儿子为vi,则易知dp ...

  7. File "/struts-tags" not found

    前言 由于在某个jsp引用了struts标签库,导致该错误产生--这是stuts项目算是一道经典错误,往往最后的解决方式是更换Tomcat.今天我记录的是引起这一错误的一个非常隐藏的原因. 错误描述 ...

  8. xcodebuild和xcrun实现自动打包iOS应用程序

    随着苹果手持设备用户的不断增加,ios应用也增长迅速,同时随着iphone被越狱越来越多的app 的渠道也不断增多,为各个渠道打包成了一件费时费力的工作,本文提供一种比较智能的打包方式来减少其带来的各 ...

  9. 一个包的TcpServer流程

    上次说到对于那种有内容的包 bool TCPServer::on_receive_data(int channel_id, void* data, int len) { packet pkt; { p ...

  10. 7-Highcharts曲线图之分辨带

    <!DOCTYPE> <html lang='en'> <head> <title>7-Highcharts曲线图之分辨带</title> ...