`

java实现cache的基本原则

 
阅读更多

我这里说的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 的数据网格平台项目所替代。
分享到:
评论

相关推荐

    Cache的简单实现(java版)

    本文将详细介绍如何使用Java实现三种常见的缓存策略:随机缓存(Random)、先进先出缓存(FIFO)以及最近最不常用缓存(LRU)。 首先,我们来理解缓存的基本概念。缓存是一种存储层,位于主内存和CPU之间,用于快速...

    a simple cache for android and java.zip

    "a simple cache for android and java.zip" 提供的可能是一个简洁的缓存实现,方便开发者快速集成到自己的项目中。下面我们将详细探讨缓存的基本概念、工作原理以及在Android和Java中的应用。 1. **缓存基本概念**...

    医疗行业,Cache 面向对象软件开发 教程

    4. **集成Cache到面向对象系统**:指导如何在Java、C#等面向对象语言中集成Cache服务,包括配置、API使用、异常处理等。 5. **性能优化与最佳实践**:分享在医疗系统中使用Cache的性能优化技巧,如预热Cache、容量...

    JAVA上百实例源码以及开源项目源代码

    Java实现的FTP连接与数据浏览程序 1个目标文件 摘要:Java源码,网络相关,FTP Java实现的FTP连接与数据浏览程序,实现实例化可操作的窗口。 部分源代码摘录: ftpClient = new FtpClient(); //实例化FtpClient对象 ...

    LRUCache:用Java实现的小型LRUCache。 不顾编码测试而制造

    LRUCache(Least Recently Used Cache)是一种常用的缓存淘汰策略,它基于“最近最少使用”的原则,当缓存满时,会优先淘汰最近最不常使用的数据。在Java中实现LRUCache,我们可以利用Java 8引入的`java.util....

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    框架实现 log4j logback commong logging jdk logger 测试框架 测试框架 junit easymock testng mockito bug管理 禅道 jira 开发工具 编程工具 eclipse myeclipse idea vi VS webstorm ...

    java编程ATM取款机系统

    Java编程中的ATM取款机系统是一个典型的模拟实际生活中银行自动柜员机操作的应用程序,它涉及到了许多关键的编程概念和技术。...通过这个项目,开发者不仅可以提升Java编程技能,还能深入理解软件工程的实践原则。

    java英汉字典

    这可以通过Java的文件系统操作或者内存缓存库如Guava Cache来实现。 8. **事件驱动编程**:GUI应用通常采用事件驱动模型,当用户进行操作(如点击查询按钮)时,相应的事件处理器会被触发。JavaFX和Swing都提供了...

    阿里巴巴Java开发手册(公开版).pdf

    这份手册详细涵盖了Java编程中的各种最佳实践、编码规范、设计模式以及系统设计原则,对于提高开发效率、减少代码维护难度具有重要意义。 一、编码规范 1. 命名规范:阿里巴巴Java开发手册强调了变量、方法、类等...

    JAVA基础课程PPT

    Java中,数组、链表、栈、队列、树、图等基本数据结构和排序、查找等算法的实现是提升编程能力的关键。 "6.常用工具集"可能包括JUnit(单元测试)、Maven(项目管理)、Git(版本控制)等,这些工具是Java开发者的...

    java题目以及Java面试题和ASP.NET的技术题目java题目以及Java面试题和ASP.NET的技术题目java题目以及Java面试题和ASP.NET的技术题目

    【Java题目及面试题】 ...以上只是Java和ASP.NET的部分知识点,实际的面试和学习中还需要深入理解其他领域,如网络编程、数据库设计、软件工程原则等,不断积累实战经验,才能成为优秀的IT专业人士。

    Manning.Java.Persistence.with.Hibernate.Nov.2006.pdf

    3. **实体类设计**:书中会讨论如何设计符合ORM原则的Java实体类,包括属性、构造函数、getter/setter方法,以及如何使用JPA注解如@Entity、@Id、@GeneratedValue等来标记实体类和其主键。 4. **映射文件**:书中会...

    Java知识体系+ 总结+面试

    1. **Java体系总结1**:这部分内容可能包括了Java的基础概念,如变量、数据类型、运算符、流程控制语句(if-else、switch、for、while等),以及类、对象、封装、继承和多态等面向对象编程的基本原则。 2. **技术人...

    JAVA课程设计院学不有代码还不象牙的

    在Java课程设计中,理解代码编写的基本原则和技巧是至关重要的。Code-Behind技术是一种常见的代码分离策略,它在.NET框架中广泛使用,但同样适用于许多其他编程环境,包括Java。Code-Behind允许开发者将用户界面(UI...

    Java并发编程与高并发解决方案-学习笔记-www.itmuch.com.pdf

    本文将基于文档《Java并发编程与高并发解决方案-学习笔记***.pdf》中提供的内容,来详细阐述并发编程和高并发的基本概念、CPU多级缓存与缓存一致性、以及Java内存模型。 ### 并发与高并发概念 在现代多线程编程中...

    LRUCache实现 同步LRUCache

    LRUCache(Least Recently Used Cache)是一种常用的缓存淘汰策略,它基于“最近最少使用”的原则,当缓存满时,会优先淘汰最近最不常使用的数据。在Java中,虽然标准库没有直接提供LRUCache,但我们可以通过自定义...

    阿里巴巴Java开发手册(终极版)

    - 设计原则:遵循SOLID原则,包括单一职责、开闭原则、里氏替换、接口隔离和依赖倒置。 - 构造函数:私有化构造器,推荐使用Builder模式或工厂方法创建对象。 - 静态工厂方法:比构造函数更灵活,不破坏封装性,...

    xutils:java基本工具类

    mix模块说明Cache模块实现了一套本地缓存。concurrent模块对JDK自带的任务调度API进行了简单的封装。jdbc模块主要是对SQL语法串的拼接操作等封装。io模块主要是对File文件操作的api封装http对Java原生的URLCon

    android代码优化原则.doc

    对于处理字符串等操作,优先使用Java内置的高效原生方法,如String.indexOf()和String.lastIndexOf(),它们由C/C++实现,性能远超纯Java循环。然而,谨慎使用native方法,因为调用它们会有额外开销,不适合进行简单...

Global site tag (gtag.js) - Google Analytics