`
w800927
  • 浏览: 119978 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java基本类实现二级缓存

阅读更多

LRU linkedhashmap中由于重写 removeEldestEntry后只能一个一个的删除,如果删除后的内容需要持久化的话将会影响效率,因此需要批量转储,如果能访问hashmap的header after等私有变量就好了,可是未遂

本人解决方案如下:
首先将要删除的linkedhashmap中的removeEldestEntry(java.util.Map.Entry<K, V> eldest)真正删除,然后将最终元素记录到缓冲map中,作为一个cache,然后在批量转储

 

import java.util.LinkedHashMap;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
*
* @param <K>
* @param <V>
* 定长 LRU hashmap 当长度超过maxCapacity自动删除最不常访问的元素
*/
public class LRULinkedHashMap<K, V> extends LinkedHashMap<K, V> {
private final int maxCapacity;
private static LinkedHashMap batchToDelete = new LinkedHashMap();
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
private final Lock lock = new ReentrantLock();

public LRULinkedHashMap(int maxCapacity) { // false是插入顺序
super(maxCapacity, DEFAULT_LOAD_FACTOR, false);
this.maxCapacity = maxCapacity;
}

@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
boolean needRemove = false;
// 转储待写代码 eldest将要被删除的元素 还需要维护 accidsessions的删除操作
if (size() >= maxCapacity * Constants.RANGETODELETE) {
batchToDelete.put(eldest.getKey(), eldest.getValue());
needRemove = true;
}
System.err.println(batchToDelete.size());
if (batchToDelete.size() > maxCapacity * Constants.TODELETECACHE) {
this.cleanEntitiesInLRU();
}
return needRemove;
}

private void cleanEntitiesInLRU() {
try {
Set<K> keyset = batchToDelete.keySet();
// 批量转储息道此处,可通过另起线程监听由另外线程完成
System.err.println(batchToDelete.size() + " 待删区个数");
// for (K k : keyset) {
// this.remove(k);
// }
batchToDelete.clear();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}

@Override
public V get(Object key) {
return super.get(key);
// try {
// lock.lock();
// }
// finally {
// lock.unlock();
// }
}

@Override
public V put(K key, V value) {
try {
lock.lock();
return super.put(key, value);
} finally {
lock.unlock();
}
}
}

junit测试用例:

import static org.junit.Assert.*;

import org.junit.Test;

import LRULinkedHashMap;

public class TestLruHashMap {

@Test
public void testLRULinkedHashMap() {
LRULinkedHashMap<String, String> testSession=new LRULinkedHashMap<String, String>(100);
for(int i=0;i<1000;i++){
try{
Object obj = (i%3==0)?testSession.put("session "+i/3, i+" lru"):testSession.put("session "+i, i+" lru");
System.out.println(testSession.size()+" " +testSession);
}catch(Exception e){
e.printStackTrace();
}
}
}


}
LinkedBlockingQueue 可以做为队列方式的缓存实现 优势:引入了两个锁,一个入队列锁,一个出队列锁。当然同时有一个队列不满的Condition和一个队列不空的Condition。其实参照锁机制前面介绍过的生产者-消费者模型就知道,入队列就代表生产者,出队列就代表消费者。为什么需要两个锁?一个锁行不行?其实一个锁完全可以,但是一个锁意味着入队列和出队列同时只能有一个在进行,另一个必须等待其释放锁。而从ConcurrentLinkedQueue的实现原理来看,事实上head和last (ConcurrentLinkedQueue中是tail)是分离的,互相独立的,这意味着入队列实际上是不会修改出队列的数据的,同时出队列也不会修改入队列,也就是说这两个操作是互不干扰的。更通俗的将,这个锁相当于两个写入锁,入队列是一种写操作,操作head,出队列是一种写操作,操作tail。可见它们是无关的。但是并非完全无关,后面详细分析

http://www.blogjava.net/xylz/archive/2011/02/15/326988.html

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Mybatis-plus基于redis实现二级缓存过程解析

    Mybatis-plus基于Redis实现二级缓存过程解析 Mybatis-plus是一款基于Java语言的持久层框架,旨在简化数据库交互操作。然而,在高并发、高性能的应用场景中,数据库的查询操作可能会成为性能瓶颈。为了解决这个问题...

    Redis用作二级缓存

    将Redis集成到Mybatis的二级缓存中,可以实现跨SqlSession的数据共享,即使在不同的会话或请求之间,也可以复用之前查询的结果。 配置Redis作为Mybatis的二级缓存,需要以下几个步骤: 1. 添加依赖:在项目的pom....

    MyBatis缓存(一级缓存、二级缓存)

    二级缓存的实现基于MyBatis的插件体系,可以通过配置启用并指定实现类,如 EhCache 或 Redis。 启用二级缓存需要在MyBatis的配置文件中开启缓存支持,并在对应的Mapper接口或XML配置中声明启用二级缓存。每个Mapper...

    二级缓存配置

    这里指定了使用EhCache作为二级缓存的实现。EhCache是一种广泛使用的高性能纯Java缓存库,能够很好地集成到Hibernate中。 ##### 2. 配置实体缓存策略 对于需要进行缓存的实体,需要在对应的`hibernate-mapping`...

    hibernate二级缓存java包下载

    3. **实现二级缓存**: - 配置缓存插件:如 Ehcache、Infinispan 或 Hazelcast,这些插件需要添加到 Hibernate 的配置文件中,并指定对应的缓存提供商。 - 类和集合的缓存配置:在实体类上使用 `@Cacheable` 注解...

    hibernate二级缓存实例

    在Java的持久化框架Hibernate中,二级缓存是提高数据访问效率的重要机制。它是一种全局共享的、跨会话的数据存储区域,旨在减少对数据库的直接访问,从而降低系统负载,提升性能。在这个"hibernate二级缓存实例"中,...

    hibernate一级缓存、二级缓存和查询缓存

    二级缓存的实现需要依赖第三方缓存提供者,如EhCache、Infinispan等。二级缓存的主要特点包括: - **跨事务共享**:与一级缓存不同,二级缓存可以在多个事务之间共享数据,提高了数据的复用性。 - **配置复杂**:二...

    day37 05-HIbernate二级缓存:一级缓存更新同步到二级缓存及二级缓存配置文件

    二级缓存通常由第三方缓存提供商如Ehcache、Infinispan等实现。 一级缓存到二级缓存的同步是自动进行的。当对象在一级缓存中被修改并提交后,Hibernate会根据配置将这些变化同步到二级缓存中。这个过程包括了更新、...

    hibernate一级和二级缓存配置与详解

    接下来,为特定的实体类或者查询结果启用二级缓存: ```xml ``` 这里的`usage`属性可以是`read-only`、`nonstrict-read-write`、`read-write`或`transactional`,分别对应不同的缓存策略。 ### 查询缓存 查询...

    二级缓存详解

    二级缓存是指在SessionFactory级别上维护的数据缓存,它不同于一级缓存(Session级别),一级缓存在每个Session实例中保存对象,而二级缓存则跨越多个Session,甚至整个应用实例。这意味着二级缓存可以在多个用户间...

    详解Java的Hibernate框架中的缓存与二级缓存

    主要介绍了Java的Hibernate框架中的缓存与二级缓存,Hibernate是Java的SSH三大web开发框架之一,需要的朋友可以参考下

    47-二级缓存 Hibernate-Shiro-MyBatis

    Hibernate是Java开发中的一个流行对象关系映射框架,它提供了一级缓存和二级缓存。一级缓存是每个Session内的缓存,而二级缓存则可以在多个Session之间共享。Hibernate的二级缓存主要通过插件实现,如Ehcache和...

    spring二级缓存

    EhCache是一个流行的开源Java缓存解决方案,它可以被Spring和Hibernate集成来作为二级缓存提供者。在配置Spring二级缓存时,我们需要完成以下步骤: 1. **添加依赖**:首先,确保项目中包含EhCache的相关库,包括`...

    J2Cache 基于内存和 Redis 的两级 Java 缓存框架

    第一级缓存使用内存(同时支持 Ehcache 2.x、Ehcache 3.x 和 Caffeine),第二级缓存使用 Redis(推荐)/Memcached 。 由于大量的缓存读取会导致 L2 的网络成为整个系统的瓶颈,因此 L1 的目标是降低对 L2 的读取次数。 ...

    hibernate二级缓存示例源码

    本文将深入探讨Hibernate二级缓存的基本概念、工作原理及如何通过示例源码实现。 ### 1. 二级缓存概述 Hibernate的一级缓存是Session级别的,它自动管理对象的状态,提供瞬时、持久化和脱管状态之间的转换。然而,...

    hibernate 二级缓存

    在Java的持久化框架Hibernate中,二级缓存是提高应用程序性能的重要工具。它是一个全局共享的、跨会话的缓存,存储了实体对象的副本,以减少对数据库的访问次数,从而提升系统性能。本篇文章将深入探讨Hibernate二级...

    hibernate5.1二级缓存包

    这个"hibernate5.1二级缓存包"应该包含了用于实现二级缓存的相关组件和配置。 二级缓存是相对于一级缓存(Session 缓存)而言的,一级缓存是每个 Hibernate Session 内部的缓存,而二级缓存则是在 SessionFactory ...

    Ehcache二级缓存.zip

    在这个"Ehcache二级缓存.zip"压缩包中,可能包含了实现Ehcache二级缓存的相关文件,如jar包、配置文件和文档等。 1. **Ehcache二级缓存**:在Java应用中,一级缓存通常指的是JVM内的内存缓存,而二级缓存则可以是...

    mybatis+redis实现二级缓存

    在本项目中,“mybatis+redis实现二级缓存”是一个巧妙结合了MyBatis持久层框架与Redis内存数据库来优化数据访问速度的实践案例。下面将详细介绍这个项目中的关键技术点以及实现步骤。 首先,MyBatis是一个轻量级的...

Global site tag (gtag.js) - Google Analytics