Java设计实现一个针对各种类型的缓存

 更新时间:2023年11月16日 10:51:08   作者:代码哲学  
这篇文章主要为大家详细介绍了Java如何设计实现一个针对各种类型的缓存,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下

1. 设计顶层接口

// 定义为一个泛型接口,提供给抽象类使用
public interface CacheManager<T> {
    // 获取所有的缓存item
    List<T> getAll();
    // 根据条件获取某些缓存item
    List<T> get(Predicate<T> predicate);
    // 设置缓存
    boolean set(T t);
    // 设置缓存list
    boolean set(List<T> tList);
}

有接口必定有实现类或者抽象类,实现接口。

那为了更好地控制子类的行为,可以做一个抽象类,控制子类行为。

分析:

  • 抽象类作为缓存管理的话,那么就需要提供安全访问数据
  • 需要考虑线程安全问题。
  • 花絮: 不仅要满足上述需求,而且让代码尽量简洁。

2. 设计抽象类 – AbstractCacheManager

属性设计:

  • 需要一个缓存
  • 需要一个线程安全机制方案

行为设计:

自己的行为:

  • 利用线程安全机制控制缓存的读写。
  • 权限:仅自己可访问

后代的行为:

  • 访问一些简单api方法即可实现安全访问缓存
  • 权限:公共访问

设计模式:

包裹思想,将后代行为方法中,包裹一层安全访问的行为。

Java Code:

 // properties design:
protected ConcurrentMap<String, T> cache;

private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

// subclass to implements these abstract methods.

protected abstract List<T> getAllByCache();

protected abstract void setByCache(T t);

protected abstract void setByCache(List<T> tList);

protected abstract List<T> getByCache(Predicate<T> predicate);

// next content needs to consider safety of multithreads. following methods do implements.
// entry to use
@Override
public final List<T> getAll() {
   return this.readLockThenGet(() -> this.getAllByCache());
}

@Override
public final List<T> get(Predicate<T> predicate) {
   return this.readLockThenGet(pre -> getByCache(pre), predicate);
}

@Override
public final boolean set(T t) {
   return this.writeLockThenSet((Consumer<T>) obj -> set(obj), t);
}

@Override
public final boolean set(List<T> tList) {
   return this.writeLockThenSet((Consumer<List<T>>) list -> set(list), tList);
}

// current abstract class access cache object.
private boolean writeLockThenSet(Consumer consumer, Object object){
    boolean wLock = false;
    try {
        if (!(wLock = lock.writeLock().tryLock(100, TimeUnit.MICROSECONDS))) {
            return false;
        }
        consumer.accept(object);
        return true;
    } catch (Exception e) {
        return false;
    } finally {
        if(wLock) {
            lock.writeLock().unlock();
        }
    }
}

private List<T> readLockThenGet(Supplier<List<T>> supplier){
    boolean rLock = false;
    try{
        if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){
            return null;
        }
        return supplier.get();
    }catch (Exception e){
        return null;
    }finally {
        if(rLock) {
            lock.readLock().unlock();
        }
    }
}

private List<T> readLockThenGet(Function<Predicate<T>, List<T>> function, Predicate<T> predicate){
    boolean rLock = false;
    try{
        if(!(rLock = lock.readLock().tryLock(100, TimeUnit.MICROSECONDS))){
            return null;
        }
        return function.apply(predicate);
    }catch (Exception e){
        return null;
    }finally {
        if(rLock) {
            lock.readLock().unlock();
        }
    }
}

3. 具体子类

3.1 – AlertRuleItemExpCacheManager

@Component("alertRuleItemExpCacheManager")
public class AlertRuleItemExpCacheManager<T extends AlertRuleItemExpCache> extends AbstractCacheManager<AlertRuleItemExpCache> {
   @Resource
   private AlertRuleItemExpDao alertRuleItemExpDao;

   @Override
   protected List<AlertRuleItemExpCache> getAllByCache() {
       if (null == cache) {
           List<AlertRuleItemExp> alertRuleItemSrcList =
                   alertRuleItemExpDao.selectList(Wrappers.<AlertRuleItemExp>lambdaQuery().eq(AlertRuleItemExp::getDeleted, 0));
           cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache())
                   .collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));
       }
       return cache.values().stream()
               .sorted(Comparator.comparing(AlertRuleItemExpCache::getId))
               .collect(Collectors.toList());
   }

   @Override
   protected void setByCache(AlertRuleItemExpCache alertRuleItemExpCache) {
       cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache);
   }

   @Override
   protected void setByCache(List<AlertRuleItemExpCache> alertRuleItemExpCacheList) {
       alertRuleItemExpCacheList.parallelStream().forEach(alertRuleItemExpCache ->
               cache.put(alertRuleItemExpCache.getId().toString(), alertRuleItemExpCache));
   }

   @Override
   protected List<AlertRuleItemExpCache> getByCache(Predicate<AlertRuleItemExpCache> predicate) {
       return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());
   }
}

3.2 – AlertRuleItemSrcCacheManager

@Component("alertRuleItemSrcCacheManager")
public class AlertRuleItemSrcCacheManager<T extends AlertRuleItemSrcCache> extends AbstractCacheManager<AlertRuleItemSrcCache> {
   @Resource
   private AlertRuleItemSrcDao alertRuleItemSrcDao;

   @Override
   protected List<AlertRuleItemSrcCache> getAllByCache() {
       if (null == cache) {
           List<AlertRuleItemSrc> alertRuleItemSrcList =
                   alertRuleItemSrcDao.selectList(Wrappers.<AlertRuleItemSrc>lambdaQuery().eq(AlertRuleItemSrc::getDeleted, 0));
           cache = alertRuleItemSrcList.stream().map(entity -> entity.toCache())
                   .collect(Collectors.toConcurrentMap(cache -> cache.getId().toString(), cache -> cache));
       }
       return cache.values().stream()
               .sorted(Comparator.comparing(AlertRuleItemSrcCache::getId))
               .collect(Collectors.toList());
   }

   @Override
   protected void setByCache(AlertRuleItemSrcCache alertRuleItemSrcCache) {
       cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache);
   }

   @Override
   protected void setByCache(List<AlertRuleItemSrcCache> alertRuleItemSrcCacheList) {
       alertRuleItemSrcCacheList.parallelStream().forEach(alertRuleItemSrcCache ->
               cache.put(alertRuleItemSrcCache.getId().toString(), alertRuleItemSrcCache));
   }

   @Override
   protected List<AlertRuleItemSrcCache> getByCache(Predicate<AlertRuleItemSrcCache> predicate) {
       return getAllByCache().stream().filter(cache -> predicate.test(cache)).collect(Collectors.toList());
   }
}

4. 类图关系

以上就是Java设计实现一个针对各种类型的缓存的详细内容,更多关于Java缓存的资料请关注脚本之家其它相关文章!

相关文章

  • Java基本数据类型和运算符详解

    Java基本数据类型和运算符详解

    这篇文章主要介绍了Java基本数据类型和运算符,结合实例形式详细分析了java基本数据类型、数据类型转换、算术运算符、逻辑运算符等相关原理与操作技巧,需要的朋友可以参考下
    2020-02-02
  • Java中字符串拼接的一些细节分析

    Java中字符串拼接的一些细节分析

    这篇文章主要介绍了Java中字符串拼接的一些细节分析,本文着重剖析了字符串拼接的一些性能问题、技巧等内容,需要的朋友可以参考下
    2015-01-01
  • 通过Mybatis实现单表内一对多的数据展示示例代码

    通过Mybatis实现单表内一对多的数据展示示例代码

    最近做项目遇到这样的需求要求将表中的数据,按照一级二级分类返回给前端json数据,下面通过本文给大家分享通过Mybatis实现单表内一对多的数据展示示例代码,感兴趣的朋友参考下吧
    2017-08-08
  • Java定时任务原理详解

    Java定时任务原理详解

    当下,java编码过程中,实现定时任务的方式主要以以下两种为主:spring框架的@Scheduled和quzrtz框架。本文主要就二者的框架原理实现做一个入门引导,为了解深层实现细节做一定的铺垫
    2022-07-07
  • java获取nvidia显卡信息的实现示例

    java获取nvidia显卡信息的实现示例

    现在的需求是要获取nvidia显卡的使用情况,本文主要介绍了java获取nvidia显卡信息的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • java poi之XWPFDocument如何读取word内容并创建新的word

    java poi之XWPFDocument如何读取word内容并创建新的word

    这篇文章主要介绍了java poi之XWPFDocument如何读取word内容并创建新的word问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • SpringBoot项目里集成Hibernate的示例

    SpringBoot项目里集成Hibernate的示例

    在Spring Boot项目中,集成Hibernate可以帮助我们更轻松地进行数据库操作,本文将介绍如何在Spring Boot项目中集成Hibernate,并提供相应的示例,感兴趣的朋友跟随小编一起看看吧
    2023-04-04
  • 如何使用Spring Cloud Feign日志查看请求响应

    如何使用Spring Cloud Feign日志查看请求响应

    这篇文章主要介绍了如何使用Spring Cloud Feign日志查看请求响应,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • java基本教程之java线程等待与java唤醒线程 java多线程教程

    java基本教程之java线程等待与java唤醒线程 java多线程教程

    这篇文章主要介绍了对线程等待/唤醒方法,文中使用了多个示例,大家参考使用吧
    2014-01-01
  • IntelliJ IDEA 统一设置编码为utf-8编码的实现

    IntelliJ IDEA 统一设置编码为utf-8编码的实现

    这篇文章主要介绍了IntelliJ IDEA 统一设置编码为utf-8编码的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2020-06-06

最新评论