使用软引用实现缓存机制

HashMap + 软引用进行缓存 */ private ReferenceQueue queue; /** 真正的map对象 1、temp 内部 封装的 Node 强引用 K 和 SoftNode 2、SoftNode 内部强引用K,弱引用真正的Value */ private HashMap<K, SoftNode<K, V>> temp; public SoftHashMap() { queue = new ReferenceQueue<>(); temp = new HashMap& 阅读详情

“读多写少”是大部分项目的一个特点。例如“购物”,总是看的人多(读)、买的人少(写)。因此,如果能减少“读”请求的次数,就能减少服务端的压力。最直接的减少“读”请求次数的方法就是使用缓存。

软引用和强引用

对于同一个读请求,只需要在第一次访问时从数据库中查询数据,并将查询到的数据保存到缓存中,之后的查询请求就可以直接在缓存中获取,从而减少对数据库的访问次数。

这种情况我们生活种经常会看到,比如访问某app某商品,第一次进去会加载一会会,后面继续点击是直接出现。

根据目前所学知识,我们可以使用 HashMap 在内存级别实现缓存功能。例如,可以使用一个 HashMap 对象保存客户端第一次请求的结果,之后,当客户端再次发起读请求时,就从 HashMap 对象中遍历查询,如果 HashMap 中已经保存过客户要查询的数据,就直接返回,否则再向数据库发起查询请求,并将查询结果保存到 HashMap 中。

这种缓存的设计思路十分简单,但也存在一个问题:HashMap 中缓存的数据何时被清空?

内存容量是有限制的,如果永无止尽的向 HashMap 缓存数据,显然会对内存容量带来压力。一种解决方案就是使用 JVM 提供的软引用,实现对 HashMap 中缓存数据的淘汰策略。

开发中最常使用的是强引用,例如 Goods goods = new Goods() 就创建了一个强引用对象“goods”。只要强引用的作用域没有结束,或者没有被开发者手工设置为 null,那么强引用对象会始终存在于 JVM 内存中。

而 JVM 提供的软引用就比较灵活:当 JVM 的内存足够时,GC 对待软引用和强引用的方式是一样的;但当 JVM 的内存不足时,GC 就会去主动回收软引用对象。可见,非常适合将缓存的对象存放在软引用中。软引用需要借助 JDK 提供的 java.lang.ref.SoftReference 类来实现。

项目

使用idea创建一个maven项目

结构如下

首先对Good实体类进行编写。

要求,goods有属性id,name并书写他的getset方法,以及有参无参构造器。

这里代码省略。

然后我们在goodbase里面编写代码,模拟一个数据库

里面主要有hashmap,并且通过get方法,得到该hashmap

public class GoodsBase {

    private static Map<String, Goods> base = new HashMap<>();

    public static Map<String, Goods> getBase() {
        return base;
    }
}

然后书写goodscache缓存类

这里我们需要接触一个新关键字volatile

  1. 使用volatile关键字会强制将修改的值立即写入主存;
  2. 使用volatile关键字的话,当主线程修改时,会导致RunThread的工作内存中isRunning变量的缓存值变得无效。
  3. 由于RunThread的工作内存中缓存变量isRunning缓存无效,所以会再次从主存中读取isRunning变量值。

在map里面通过泛型把缓存对象存储在软引用里面(map里面)

代码如下:

public class GoodsCache {

    private volatile static GoodsCache goodsCache;

    public GoodsCache(){
        this.cache = new HashMap<>();
    }

    public static GoodsCache getGoodsCache() {
        if(goodsCache == null) {
            synchronized (GoodsCache.class){
                if(goodsCache == null){
                    goodsCache = new GoodsCache();
                }
            }
        }
        return goodsCache;
    }

    // 将缓存对象存储在软引用中
    private Map<String, SoftReference<Goods>> cache;

    // 根据id存储缓存Goods对象
    public void setCache(Goods goods) {
        cache.put(goods.getId(), new SoftReference<Goods>(goods));
        System.out.println("添加数据到缓存成功");
    }

    // 根据id从缓存中获取对象
    public Goods getCache(String id) {
        // 根据id,获取缓存对象的软引用
        SoftReference<Goods> softRef = cache.get(id);
        return softRef == null ? null : softRef.get();
    }

    public void delCache(String id) {
        cache.remove(id);
        System.out.println("从缓存删除数据成功");
    }
}

接下来我们书写goodsservice代码,来模拟数据库增删改查,不过我们是通过id来进行

public class GoodsService {

    GoodsCache goodsCache = GoodsCache.getGoodsCache();

    public Goods getById(String id){
        if(goodsCache.getCache(id) == null){
            Goods goods = GoodsBase.getBase().get(id);
            goodsCache.setCache(goods);
            System.out.println("从数据库读取数据");
            System.out.println(goods.getName());
            return goods;
        }
        System.out.println(goodsCache.getCache(id).getName());
        return goodsCache.getCache(id);
    }

    public void add(Goods goods){
        goodsCache.setCache(goods);
        GoodsBase.getBase().put(goods.getId(), goods);
        System.out.println("添加数据到数据库");
    }

    public void deleteById(String id){
        if(goodsCache.getCache(id) != null){
            goodsCache.delCache(id);
        }
        GoodsBase.getBase().remove(id);
    }
}

最后我们书写test文件

运行结果

可以看到第二次运行 goodsService.getById("1"); 是从缓存中直接读取的数据,也可以看出,其实用软引用实现缓存机制,读取的对象是同一个对象。

HashMap + 软引用进行缓存,2021年Java知识体系总结 private HashMap<K, SoftNode<K, V>> temp; public SoftHashMap() { queue = new ReferenceQueue<>(); temp = new HashMap<>(); } @Override public V get(Object key) { clearQueue(); // 通过 key进行取值,如果为null,返回null,否则 阅读详情

相关推荐

显著性算法 + 伪彩变换

利用opencv得到显著图和伪彩图

正在挣扎中的人 2301

工具类:Map实现软/弱引用

JDK提供的软/弱引用可以直接应用在某一对象,此处基于 JDK 提供的软/弱引用功能,实现Map的软/弱引用。(本质是map value值的软/弱引用) 实现有两个版本: JDK1.8之前的常规实现(继承实现) JDK1.8 FunctionInterface 版本 JDK1.8之前的常规实现 AbstractReferenceMap<K, V> 定义抽象接口,其有两个实现: S...

super_wj0820的博客 1148

在 SAP 中修改 Profile 文件中的主机名需要谨慎操作,需需确保所有相关配置保持一致

在SAP系统中修改Profile文件主机名需谨慎操作,主要步骤包括:1)停止相关SAP服务;2)重命名并编辑实例级Profile文件(如ER1_D00_OLDHOST改为ER1_D00_LRPSAP),修改所有含旧主机名的参数;3)可选更新默认Profile文件;4)在Windows系统中调整注册表配置;5)验证一致性后重启服务。关键注意:保持大小写统一、修改前备份文件、集群环境需同步所有节点。通过系统日志确认新主机名生效且无报错。

金牌架构师 1052

java利用软引用实现jvm缓存

在某些不存在缓存中间件的系统中,需要用到缓存,大多数时候都是使用map,但是map会占jvm内存,并且不会回收,缓存量大的情况会经常出现OOM错误,这时候就可以使用java的软引用结合map一起实现缓存机制。对于java的四种引用类型:强引用,软引用,弱引用,虚引用,这里就不做详细介绍。声明一下,软引用会在发生OOM之前,回收其中的对象。下面使用软引用结合map写一个对于内存敏感的高...

ly199108171231的博客 1645

LVGL colorwheel组件教程一(调色板)

【代码】LVGL colorwheel组件教程一(调色板)

摸鱼专家 454

ESP-SPARKBOT AI 智能机器人:v1.2 全流程复刻指南

本文介绍 ESP-SPARKBOT AI 智能机器人 v1.2 版本的全流程复刻,包含 PCB 、3D 打印、固件烧录、常见问题解决、参考资料等

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 9260

Android 软引用内存缓存图片

1,实现效果 内存不足的时候使用Map集合强引用 ,不容易被释放,我使用SoftReference 2,实现逻辑 引用 【1】使用软引用进行,叫系统内存不足时能快点进行释放 ,软引用在版本更改后会被很快的释放 package com.utils.pic; import android.graphics.Bitmap; import android.support...

Cricket_7的博客 308

ADAS工作原理解析:如何通过智能技术提升驾驶安全

ADAS通过集成传感器、摄像头、雷达、SoC计算单元以及高效的数据融合技术,提供了一系列主动和被动安全功能,如自动刹车、车道保持、自适应巡航控制等。这些功能共同作用,不仅减少了交通事故的发生,还大幅提升了驾驶员的驾驶体验和安全性。随着技术的进步,ADAS的功能将越来越智能,最终迈向全自动驾驶的未来🚗💨。

weixin_43199439的博客 1150

Android 图片缓存之内存缓存技术LruCache,软引用

转自:http://blog.chinaunix.net/uid-26930580-id-4138306.html

Gabriel的专栏 2万+

Vue3 - [最强] 超详细 Element Plus 组件库主题颜色进行 “统一全局“ 替换,将默认的蓝色主题色更换为其他自定义颜色,覆盖原来的主题色改为自己的颜色(完美解决主题色不生效、没反应)

elementplus修改主题色,vue3+element-plus主题色更换,vue3vite如何修改扩展elementplus主题色样式,全局设置elementplus主题色,有什么办法可以直接全局修改主题色,对elementplus默认蓝色不满意怎么替换更改其他颜色,elementplus覆盖默认主题色,elementplus主题色官方文档,vue3中修改elementplus主题色,elementplus修改主题色不生效怎么办,elementplus如何修改主题颜色,eleme

🏆 前端领域优质创作者 1万+

AUTOSAR SHE 密钥更新协议

依赖内存槽的使用用例,内存槽有不同的保护协议。M2是新的计数值C_ID‘,相应的标志位F_ID',0填充第一个块,以及新的密钥K_ID'的组合的CBC算法加密的消息。例如,我要更新一个MASTER_ECU_KEY, 那么参考上表,我需要知晓Non-volatile的MASTER_ECU_KEY (即授权密文为MASTER_ECU_KEY自己的密文).内存的更新协议分为两部分,第一部分是实际内存更新到发送一个秘密且真实的key到SHE,然后第二部分为验证,即提供给后台一个key更新成功的证据。

weixin_46481662的博客 3285

图片缓存之内存缓存技术LruCache,软引用

这篇博文要讲的图片缓存机制,我接触到的有两钟,一种是软引用,另一种是内存缓存技术。 先来看下两者的使用方式,再来作比较。 除了加载图片时要用到缓存处理,还有一个比较重要的步骤要做,就是要先压缩图片。1、压缩图片 至于要压缩到什么状态就要看自己当时的处境了,压缩图片的时候既要达到一个小的值,又不能让其模糊 ,更不能拉伸图片。/** * 加载内存卡图片 */

reforgetYZ的博客 457

uniapp | vue2 | vue3 - 解决调用天地图功能服务时 http 网络请求报错 net::ERR ABORTED 503(Service Temporarily Unavailabl)

vue,uni-app,天地图,请求报错,503,请求失败,map.tianditu,天地图503,天地图请求503,接口503错误怎么办,vue天地图,uniAPP天地图,获取定位接口服务器报错503,获取当前定位,定位功能,IP属地定位,天地图服务器报错,如何解决报错,net::ERRABORTED503(ServiceTemporarilyUnavailabl),GET,POST,服务暂时不可用,react天地图,一直等待吗,报错怎么办,定位报错,轨迹,经纬度,天地图服务器503,在vue2

🏆 前端领域优质创作者 4439

使用软引用构建缓存

转载:http://www.devdiv.com/Android-%E4%BD%BF%E7%94%A8%E8%BD%AF%E5%BC%95%E7%94%A8%E6%9E%84%E5%BB%BA%E7%BC%93%E5%AD%98-thread-130476-1-1.html 一、为什么要使用软引用        在上面关于软引用的介绍中,已经提到了软引用的特性。使用Soft

Barving的专栏 623

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

Android 图片缓存之内存缓存技术LruCache 软引用

Android 图片缓存之内存缓存技术LruCache 软引用

gfuugff的博客 109

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

JVM软引用:内存管理核心机制

在当今的软件开发领域,内存管理是确保应用程序稳定性和性能的关键。特别是在Java虚拟机(JVM)中,内存管理策略的合理运用对于避免内存泄漏和提升系统效率至关重要。一个典型的场景是,在开发大数据处理应用时,由于内存泄漏和未及时回收无用对象,系统可能会频繁出现内存溢出错误,严重影响了应用的正常运行。为了解决这一问题,JVM引入了软引用这一核心知识点。软引用(SoftReference)是Java中一种特殊的引用类型,它提供了一种可以由JVM在内存不足时回收的对象引用。

我是Java程序员廖志伟,感谢朋友们的支持! 1168

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Java 缓存

强引用,软引用,弱引用,虚引用这里就不多说了,百度下就好了。缓存使用的是softreference。注意需要jvm参数中需要加上启动时需要加上-Xms5M -Xmx5M -XX:-UseGCOverheadLimit -XX:+PrintGCDetails -XX:+PrintReferenceGC -XX:SoftRefLRUPolicyMSPerMB=0import org.slf4j.L...

Biu Biu Biu ~~~~~ 410

Java内存管理之软引用(Soft Reference)

软引用(Soft  Reference)的主要特点是具有较强的引用功能。只有当内存不够的时候才回收这类内存,因此在内存足够的时候,他们通常不被回收。另外,这些引用对象还能保证在Java  抛出OutOfMemory异常之前,被设置为null。他可以用于实现一些常用资源的缓存,实现Cache的功能,保证最大限度的使用内存而不引起OutOfMemory异常。     下面是软引用的实现代码:impor

张勤一 2908

android缓冲机制,Android 缓存机制

相册图片预取缓存策略是内存缓存(硬引用LruCache、软引用SoftReference)、外部文件缓存(context.getCachedDir()),缓存中取不到的情况下再向服务端请求下载图片。同时缓存三张图片(当前预览的这张,前一张以及后一张)。1.内存缓存[html] view plaincopy//需要导入外部jar文件 android-support-v4.jarimport andr...

weixin_42298973的博客 371

【Android】通过软引用实现图片缓存,防止内存溢出

原文地址:http://www.cnblogs.com/dwinter/archive/2012/01/30/2331556.html 软引用相关知识传送门:http://blog.youkuaiyun.com/donglinlucky/article/details/2845777   public class BitmapCache { static private

挨踢大杂烩 1437

利用软引用实现简单的缓存

前言: 前面已经可以看到软引用的缓存方式,不过还不够具体这里专门写一个类来实现缓存: public class Cache { private HashMap&lt;Object,ObjectRef&gt; SoftCache;//用于cache内容的存储 private ReferenceQueue&lt;Object&gt; queue;//referen...

深秋凌冽的博客 1383

软引用学习笔记

软引用是Java中的一种引用类型,用于描述那些还有用但非必须的对象。当JVM内存不足时,垃圾收集器会根据软引用的引用关系来判断是否回收这些对象。与强引用不同,软引用所引用的对象在内存不足时会被回收,因此其生命周期比强引用更短。由于软引用的这一特性,它常常被用作缓存处理。当应用内存将要被耗尽时,垃圾处理器会回收软引用所指向的对象,从而释放内存。

m0_64086416的博客 460
上一篇: Java运行方式、程序结构以及notepad++
下一篇: 聊透常见设计模式之单例模式
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值