当前位置: 首页 > web >正文

高效缓存设计的哲学

文章目录

    • 引言
    • 基于缓存存储运算结果
    • 锁分段散列减小锁粒度
    • 异步化提升处理效率
    • 原子化避免重复运算
    • 小结
    • 参考

引言

基于缓存存储运算结果

利用缓存避免非必要的计算,提升结果获取速度,但还是存在问题,每个线程都需要等待锁才能看结果和运算:

 public final Map<Integer, Integer> cache = new HashMap<>();public synchronized int compute(int arg) {if (cache.containsKey(arg)) {//若存在直接返回结果return cache.get(arg);} else {//若不存在则计算并返回int result = doCompute(arg);cache.put(arg, result);return result;}}private int doCompute(int key) {ThreadUtil.sleep(500);return key << 1;}

锁分段散列减小锁粒度

利用分段锁分散压力,但是运算耗时可能导致重复计算和put操作:

public final Map<Integer, Integer> cache = new ConcurrentHashMap<>();public int compute(int arg) {Integer res = cache.get(arg);if (res == null) {int result = doCpmpute(arg);cache.put(arg, result);}return res;}private int doCpmpute(int arg) {ThreadUtil.sleep(3000);return arg << 1;}

异步化提升处理效率

使用future避免计算的阻塞,当然因为判空和创建任务非原子操作,很可能还是出现重复计算的情况:

public final Map<Integer, FutureTask<Integer>> cache = new ConcurrentHashMap<>();public int compute(int key) throws ExecutionException, InterruptedException {FutureTask<Integer> f = cache.get(key);if (f == null) {FutureTask<Integer> futureTask = new FutureTask<>(() -> doCompute(key));//缓存保证下一个线程看到时直接取出使用cache.put(key, futureTask);futureTask.run();f=futureTask ;}return f.get();}private int doCompute(int arg) {ThreadUtil.sleep(3000);return arg << 1;}

原子化避免重复运算

原子操作避免重复计算,并发运算一个数字时都采用同一个任务的结果

public int compute(int key) throws ExecutionException, InterruptedException {FutureTask<Integer> f = cache.get(key);if (f == null) {FutureTask<Integer> futureTask = new FutureTask<>(() -> doCompute(key));//原子操作添加,若返回空说明第一次添加,则让这个任务启动,其他线程直接基于缓存中的任务获取结果f = cache.putIfAbsent(key, futureTask);if (f == null) {f = futureTask;f.run();}futureTask.run();f = futureTask;}return f.get();}

小结

参考

http://www.xdnf.cn/news/8118.html

相关文章:

  • 基于科大讯飞语音识别组件(Vue3)
  • PyInstaller 如何在mac电脑上生成在window上可执行的exe文件
  • AI 招聘系统科普:如何辨别真智能与伪自动化
  • 什么是VR实景?有哪些高价值场景?
  • 微信小程序学习基础:从入门到精通
  • 5G 网络中 DNN 的深度解析:从基础概念到核心应用
  • NMEA定位测试,硬件验证
  • 【工具】Quicker/VBA|PPT 在指定位置添加参考线
  • [Memory] 01.QEMU 内存虚拟化概览
  • Python实现PDB文件预处理
  • uniapp使用sse连接后端,接收后端推过来的消息
  • Rust 学习笔记:关于生命周期的练习题
  • Win11怎样禁止程序开机启动
  • 车载以太网网络测试-27【SOME/IP-SD简述】
  • MySQL中实现大数据量的快速插入
  • 游戏引擎学习第304天:构建与遍历图
  • 第六届电子通讯与人工智能国际学术会议(ICECAI 2025)
  • 语音控制设备的仿真/语音调试
  • Linux问题排查-磁盘IO使用率满如何分析
  • lambda表达式详解
  • leetcode 83和84 Remove Duplicates from Sorted List 和leetcode 1836
  • 设计模式-工厂模式和策略模式
  • Keil5 MDK LPC1768 RT-Thread KSZ8041NL uIP1.3.1实现UDP网络通讯(服务端接收并发数据)
  • 【web应用】vue3前端框架怎么修改logo?
  • 硬件产品死机问题
  • 蓝牙低功耗(BLE)的通信信道和包类型
  • HarmonyOS 鸿蒙应用开发基础:父组件和子组件的通信方法总结
  • linux系统启动脚本(格式问题)
  • 分布式系统设计 - 性能优化
  • Spring Cloud Gateway高并发限流——基于Redis实现方案解析