面试官:你是如何使用JDK来实现自己的缓存(支持高并发)?

数据库2025-11-05 07:06:381

需求分析

项目中经常会遇到这种场景:一份数据需要在多处共享,面试有些数据还有时效性,官何高并过期自动失效。使用K实比如手机验证码,现自发送之后需要缓存起来,缓存然后处于安全性考虑,支持一般还要设置有效期,面试到期自动失效。官何高并我们怎么实现这样的使用K实功能呢?

解决方案

 使用现有的缓存技术框架,比如redis,现自ehcache。优点:成熟,缓存稳定,支持功能强大;缺点,面试项目需要引入对应的官何高并框架,不够轻量。站群服务器使用K实  如果不考虑分布式,只是在单线程或者多线程间作数据缓存,其实完全可以自己手写一个缓存工具。下面就来简单实现一个这样的工具。

先上代码: 

import java.util.HashMap;  import java.util.Map;  import java.util.concurrent.*;  /**   * @Author: lixk   * @Date: 2018/5/9 15:03   * @Description: 简单的内存缓存工具类   */  public class Cache {   //键值对集合   private final static Map<String, Entity> map = new HashMap<>();   //定时器线程池,用于清除过期缓存   private final static ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();   /**   * 添加缓存   *   * @param key 键   * @param data 值   */   public synchronized static void put(String key, Object data) {   Cache.put(key, data, 0);   }   /**   * 添加缓存   *   * @param key 键   * @param data 值   * @param expire 过期时间,单位:毫秒, 0表示***长   */   public synchronized static void put(String key, Object data, long expire) {   //清除原键值对   Cache.remove(key);   //设置过期时间   if (expire > 0) {   Future future = executor.schedule(new Runnable() {   @Override   public void run() {   //过期后清除该键值对   synchronized (Cache.class) {   map.remove(key);   }   }   }, expire, TimeUnit.MILLISECONDS);   map.put(key, new Entity(data, future));   } else {   //不设置过期时间   map.put(key, new Entity(data, null));   }   }   /**   * 读取缓存   *   * @param key 键   * @return   */   public synchronized static Object get(String key) {   Entity entity = map.get(key);   return entity == null ? null : entity.getValue();   }   /**   * 读取缓存   *   * @param key 键   * * @param clazz 值类型   * @return   */   public synchronized static <T> T get(String key, Class<T> clazz) {   return clazz.cast(Cache.get(key));   }   /**   * 清除缓存   *   * @param key   * @return   */   public synchronized static Object remove(String key) {   //清除原缓存数据   Entity entity = map.remove(key);   if (entity == null) return null;   //清除原键值对定时器   Future future = entity.getFuture();   if (future != null) future.cancel(true);   return entity.getValue();   }   /**   * 查询当前缓存的键值对数量   *   * @return   */   public synchronized static int size() {   return map.size();   }   /**   * 缓存实体类   */   private static class Entity {   //键值对的value   private Object value;   //定时器Future    private Future future;   public Entity(Object value, Future future) {   this.value = value;   this.future = future;   }   /**   * 获取值   *   * @return   */   public Object getValue() {   return value;   }   /**   * 获取Future对象   *   * @return   */   public Future getFuture() {   return future;   }   }  } 

本工具类主要采用 HashMap+定时器线程池 实现,map 用于存储键值对数据,map的value是 Cache 的云南idc服务商内部类对象 Entity,Entity 包含 value 和该键值对的生命周期定时器 Future。Cache 类对外只提供了 put(key, value), put(key, value, expire), get(key), get(key, class), remove(key), size()几个同步方法。

当添加键值对数据的时候,首先会调用remove()方法,清除掉原来相同 key 的数据,并取消对应的定时清除任务,然后添加新数据到 map 中,并且,如果设置了有效时间,则添加对应的定时清除任务到定时器线程池。

测试 

import java.util.concurrent.ExecutionException;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.Future;  /**   * @Author: lixk   * @Date: 2018/5/9 16:40   * @Description: 缓存工具类测试   */  public class CacheTest {   /**   * 测试   *   * @param args   */   public static void main(String[] args) throws InterruptedException, ExecutionException {   String key = "id";   //不设置过期时间   System.out.println("云服务器提供商
本文地址:http://www.bzve.cn/html/28c66699305.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

全站热门

电脑计算器输入数字错误的问题(探讨计算器输入数字错误的原因和解决方法)

CSS实现水平垂直居中的1010种方式(史上最全)

为什么阿里巴巴禁止工程师直接使用日志系统(Log4j、Logback)中的 API

助你掌控微服务架构的20个Go语言项目

火影电脑系统重置教程(快速恢复系统正常运行,让电脑如新)

微服务架构有毒,何时不使用微服务?

一文简单理解“推荐系统”原理及架构

浅谈JavaScript的面向对象和它的封装、继承、多态

友情链接

滇ICP备2023006006号-39