缓存与缓冲区
术语“缓冲区”和“缓存”每每能够互换使用,可是请注意,它们表明不一样的东西。传统上,缓冲区用做数据在快实体和慢实体之间的中间临时存储,因为一方必须等待另外一方(这会影响性能),缓冲区容许整个数据块(而不是小块)同时移动,从而缓解了这种状况。数据只从缓冲区写入和读取一次,此外,至少有一方知道缓冲区是可见的。java
另外一方面,缓存根据定义是隐藏的,而且任何一方都不知道缓存的发生,它还提升了性能,可是经过让相同的数据以快速方式屡次读取来提升性能。git
你能够在这里找到关于缓冲区和缓存之间差别的进一步解释。github
缓存抽象的核心是将缓存应用于Java方法,从而根据缓存中可用的信息减小执行的次数,也就是说,每次调用目标方法时,抽象都会应用缓存行为,检查给定参数的方法是否已经执行。若是已执行,则返回缓存的结果,而没必要执行实际的方法,若是方法还没有执行,则执行该方法,并缓存结果并返回给用户,以便在下次调用该方法时返回缓存的结果。这样,对于给定的一组参数,昂贵的方法(不管是CPU绑定的仍是IO绑定的)只能执行一次,而且结果能够重用,而没必要实际再次执行该方法,缓存逻辑被透明地应用,没有任何对调用程序的干扰。spring
这种方法只适用于保证为给定输入(或参数)返回相同输出(结果)的方法,不管执行了多少次。
缓存抽象提供了其余与缓存相关的操做,好比更新缓存内容或删除一个或全部条目的能力,若是缓存处理的数据在应用程序运行过程当中可能发生更改,那么这些方法很是有用。编程
与其余在Spring Framework中的服务,缓存服务是一个抽象(不是缓存实现),须要使用实际的存储来存储缓存数据 — 也就是说,抽象使你没必要写缓存逻辑但不提供实际的数据存储。这个抽象是由org.springframework.cache.Cache
和org.springframework.cache.CacheManager
接口实现。缓存
Spring提供了该抽象的一些实现:JDK 基于缓存的java.util.concurrent.ConcurrentMap
、Ehcache 2.x、Gemfire缓存、Caffeine和JSR-107兼容缓存(例如Ehcache 3.x)。多线程
缓存抽象对多线程和多进程环境没有特殊的处理,由于这些特性是由缓存实现来处理的。
若是你有一个多进程环境(即部署在多个节点上的应用程序),则须要相应地配置缓存提供程序,根据你的用例,在多个节点上复制相同的数据就足够了,可是,若是在应用程序过程当中更改数据,则可能须要启用其余传播机制。性能
缓存特定的项与经过编程缓存交互找到的典型get-if-not-found-then- proceed-and-put-eventually代码块是直接等价的,没有应用锁,几个线程可能试图同时加载相同的项,这一样适用于驱逐。若是多个线程试图同时更新或驱逐数据,则可使用陈旧数据,某些缓存提供程序在该领域提供高级特性,有关详细信息,请参阅缓存提供程序的文档。线程
要使用缓存抽象,你须要考虑两个方面:code