Java 中如何实现懒加载

Java 预加载与懒加载对比解析 预加载(饿汉模式)和懒加载(懒汉模式)是 Java 单例模式中的两种核心实现方式,分别适用于不同场景,主要差异体现在初始化时机、线程安全性和资源利用率上。 阅读详情

Java 中如何实现懒加载

懒加载是一种常见的优化技术,它可以延迟对象的创建或初始化,直到对象第一次被使用时才进行。这种技术可以帮助我们减少资源的浪费,提高程序的运行效率。

在 Scala 中,我们可以使用关键字 lazy 来定义惰性变量,实现延迟加载(懒加载)。但是在 Java 中,我们需要使用其他的技术来实现懒加载。在本文中,我们将介绍如何使用 Java 中的 Supplier 接口和双重检查锁定模式来实现懒加载,并保证只初始化一次。

使用 Supplier 接口实现懒加载


Java 中的 Supplier 接口是一个函数式接口,用于提供类型为 T 的对象。我们可以通过传递一个 lambda 表达式给 Supplier 接口的实例来实现懒加载。

下面是一个使用 Supplier 接口实现懒加载的示例代码:

javaCopy code
import java.util.function.Supplier;

publicclassLazy<T> {
    privatefinal Supplier<T> supplier;
    private T value;

    public Lazy(Supplier<T> supplier) {
        this.supplier = supplier;
    }

    public T get() {
        if (value == null) {
            value = supplier.get();
        }
        return value;
    }
}
复制代码

在上面的代码中,我们定义了一个泛型类 Lazy<T>,并在构造函数中传入一个 Supplier<T> 对象。在 get() 方法中,我们使用 value 变量来缓存 T 类型的对象,并在需要时调用 supplier.get() 方法获取 T 类型的对象。由于 value 变量只会被初始化一次,因此能够保证只有在需要时才会初始化 value 变量。

以下是使用 Lazy 类的示例代码:

javaCopy code
publicclassLazyDemo {
    publicstaticvoidmain(String[] args) {
        Lazy<String> lazyString = new Lazy<>(() -> {
            System.out.println("Initializing lazy string...");
            return"Hello, World!";
        });

        System.out.println(lazyString.get());
        System.out.println(lazyString.get());
        System.out.println(lazyString.get());
    }
}

在上面的代码中,我们创建了一个 Lazy<String> 对象,并传入一个 lambda 表达式,用于提供 String 类型的对象。在 main() 方法中,我们多次调用 lazyString.get() 方法,并打印返回值。由于 value 变量只会被初始化一次,因此只有在第一次调用 lazyString.get() 方法时会输出 "Initializing lazy string...",后续调用时不会输出。

使用双重检查锁定模式实现懒加载


双重检查锁定模式是一种常见的用于实现懒加载的技术。它利用了同步块和 volatile 关键字来确保线程安全和懒加载。

以下是使用双重检查锁定模式实现懒加载

第一步,创建一个Java类,并声明一个泛型类型,以存储惰性计算的值。在我们的示例中,我们将使用泛型类型T,以便我们可以使用Lazy类来存储任何类型的值。

javaCopy code
public class Lazy<T> {
    private final Supplier<T> supplier;
    private volatile T result;

    public Lazy(Supplier<T> supplier) {
        this.supplier = supplier;
    }

    public T get() {
        T value = result;
        if (value == null) {
            synchronized (this) {
                value = result;
                if (value == null) {
                    value = supplier.get();result = value;
                }
            }
        }
        return value;
    }
}

在上面的代码中,我们声明了一个私有Supplier类型的成员变量supplier,它将计算值的函数作为参数传递。我们还声明了一个volatile类型的成员变量result,用于存储计算的结果,并确保在多线程环境下正确使用。

第二步,实现惰性加载的逻辑。在我们的Lazy类中,我们实现了一个get()方法,该方法返回计算结果。在get()方法中,我们使用了双重检查锁定机制来确保懒加载的正确性。在第一次调用get()方法时,我们检查result变量是否为空。如果为空,我们使用synchronized代码块来避免多个线程同时计算值。在synchronized代码块中,我们再次检查result变量是否为空,以确保在锁定时另一个线程未计算出值。如果为空,我们调用supplier.get()方法来计算值,并将结果存储在result变量中。在计算完成后,我们将值返回给调用者。

第三步,使用单例模式确保只初始化一次。为了确保只初始化一次,我们将result变量声明为volatile类型,并使用双重检查锁定机制。在计算值的过程中,如果另一个线程已经计算了值,则返回先前计算的结果。

第四步,测试我们的Lazy类是否按预期工作。在测试中,我们将创建一个名为TestLazy的类,并声明一个Lazy类型的变量,然后将一个匿名函数传递给Lazy类的构造函数来计算一个值。我们将使用该变量的值来测试惰性加载和单例模式的正确性。

来计算一个值。我们将使用该变量的值来测试惰性加载和单例模式的正确性。

javaCopy code
publicclassTestLazy {
    publicstaticvoidmain(String[] args) {
        Lazy<Integer> lazyValue = new Lazy<>(() -> {
            int result = 100 + 200;
            System.out.println("Calculating value...");
            return result;
        });

        System.out.println("Before calling get()");
        // 第一次调用int value1 = lazyValue.get();
        System.out.println("After calling get()");
        // 第二次调用int value2 = lazyValue.get();
        System.out.println("After calling get() again");

        System.out.println("value1: " + value1);
        System.out.println("value2: " + value2);

        // 判断是否为同一个对象
        System.out.println("Is same instance: " + (lazyValue == lazyValue));
    }
}

运行该测试类后,我们期望看到的输出是:

vbnetCopy code
Before calling get()
Calculating value...
After calling get()
After calling get() again
value1:300value2:300Is same instance: true复制代码

输出表明,第一次调用get()方法时,计算值的函数被调用并计算出值。在第二次调用get()方法时,我们没有看到“Calculating value…”这个输出,这证明了惰性加载的正确性。此外,我们还检查了两次获取到的值是否相等,以及对象是否是同一个实例,这证明了单例模式的正确性。

最后,我们现在已经有了一个实现懒加载的Lazy类,该类使用Supplier接口实现了惰性加载和单例模式,使得我们可以轻松地延迟计算值,同时避免了多次初始化变量的问题。

Android界面数据懒加载实现代码(Java) 因此,我们可以通过在Fragment中实现懒加载技术来延迟加载数据。懒加载是一种常见的优化技术,它可以延迟加载数据,只有当需要时才进行加载,以提高应用程序的性能和用户体验。在Android开发中,我们可以使用懒加载技术来延迟加载界面中的数据,特别是在使用ViewPager或Fragment等组件时非常有用。需要注意的是,为了使懒加载生效,我们还需要在ViewPager中正确地设置Fragment的可见性。通过上述代码,我们可以在Android界面中实现数据的懒加载,从而提高应用程序的性能和用户体验。 阅读详情

相关推荐

JAVA语言:什么是懒加载机制?

JVM没有规定什么时候加载,一般是什么时候使用这个class才会什么时候加载,但是JVM规定了什么时候必须初始化(初始化是第三步、装载、连接、初始化),只要加载之后,那么肯定是要进行初始化的,所以我们就可以通过查看这个类有没有进行初始化,从而判断这个类有没有被加载。

huanfeng_AI的博客 609

java懒加载实现

懒加载的作用主要是为了解决程序运行时会发生内存泄漏的问题,具体有以下几点: 1)当一个类不再使用时,如果它是通过加载的方式来实现,那么这个类中的静态变量就会被释放,因为静态变量是不需要加载的;在 Java中,有三种方式可以实现懒加载: 1、通过对象头来实现 2、通过继承类库来实现 首先我们需要声明一个对象,这个对象在编译期不会被加载,但是在运行期时,会被编译器加载到内存中。当运行时,如果类中的所有方法都已经加载完毕,这个类就会被加载到内存中,如果这个类没有被加载,那么就不会被加载。如果有的话就将它清除。

花生日记 4256

Java性能加速器Lazy<T>:如何优雅地实现延迟加载,让程序轻装上阵?

/ 模拟复杂的初始化操作// 自定义Lazy初始化注释说明:这里采用了静态内部类LazyHolder来实现延迟初始化。当方法首次被调用时,内部类LazyHolder才会被加载,进而初始化的实例。这种方式既保证了线程安全,也实现了延迟初始化。

java专栏 764

java实现懒加载_Java 中懒加载的正确实现方式

1.通常懒加载初始化的典型实现方式:public class LazyInit {public static Resource resource;public static Resource getResource() {if (resource == null) {resource = new Resource();}return resource;}}在单线程应用程序中,以上示例保证按预期工作...

weixin_39912368的博客 3756

使用Java实现前后端分离版本的路由懒加载

通过在前端使用Vue.js和Vue Router,配置懒加载的路由,并在后端使用Spring Boot提供API接口,实现前后端的交互。通过这种方式,可以在用户访问某个页面时,动态加载该页面所需的资源,提高页面加载速度和用户体验。在前后端分离的应用中,为了提高页面加载速度和用户体验,可以采用路由懒加载的方式,即在用户访问某个页面时再加载该页面所需的资源。这样,在用户访问某个页面时,会触发路由切换,然后根据路由配置中的懒加载设置,动态加载所需的资源,并进行相应的处理。,该接口可以返回前端所需的资源。

CodeShiftZ的博客 177

【Java设计模式】懒加载模式

Java中的懒加载设计模式将对象的初始化延迟到对象实际被需要的时候,从而最小化内存使用并减少启动时间。这种技术对于优化Java应用程序性能至关重要。

道长的博客 1427

java懒加载实现_Java 中懒加载的正确实现方式

1.通常懒加载初始化的典型实现方式:public class LazyInit {public static Resource resource;public static Resource getResource() {if (resource == null) {resource = new Resource();}return resource;}}在单线程应用程序中,以上示例保证按预期工作...

weixin_29119475的博客 1022

LCD、LED、OLED、Mini LED、Micro LED、全阵列LED、QLED、QD-OLED、QNED、AMOLED是什么意思?

LCD(液晶显示器,Liquid Crystal Display)定义:LCD 是一种利用液晶材料控制光线通过的显示技术,需依靠背光源(如冷阴极荧光灯 CCFL 或 LED)照亮液晶层以形成图像。技术原理:液晶分子在电场作用下改变排列,控制背光通过的强度和颜色。液晶本身不发光,需外部光源。特点:结构包括背光层、液晶层、彩色滤光片和偏光片。响应时间较慢,黑色表现因背光漏光而偏灰。LED(发光二极管显示,Light Emitting Diode)定义。

中国最威武的城市!武功军威-武威,铁骨铮铮! 3423

java实现懒加载_Java Web SpringMVC AJAX,实现页面懒加载数据

因为做的微信端的网页,所以在显示后台数据的时候,要么分页,要么全部加载数据,开始分页对于用户来说,其实体验不是很好,毕竟要去不断的点击下一页,但是如果我把全部数据读取出来的话,但用户可能也就看前面几条而已,那么就会造成性能的大大浪费。所以我就上网找了ajax懒加载方面的内容,成功实现了,在用户滚动的时候判断是否到达页面底部,是的话就通过ajax请求数据,然后显示出来。javascript代码$(f...

weixin_39568653的博客 292

【学习路线】 游戏客户端开发入门到进阶

游戏开发是一个交叉性极强的技术领域,对开发者提出了高维度的要求。作为初学者,不要急于求成,打牢基础、注重原理、勤于实践,你的成长将会非常快速而稳健。希望这份学习路线与书单能为你指明方向,迈出职业开发者的第一步。

hhw_hhw的博客 2126

BSW: Dcm模块配置--28服务

这个章节讲解下UDS中的28服务(Communcation Control)的配置,顾名思义,对当前ECU的通讯状态进行变更,主要设置应用报文,网络管理报文的收发控制,通常应用在刷写APP软件时,降低总线负载。这里首先要提醒的一点是,28服务几乎不需要手写代码,只有在客户需求要求前置条件不满足时报特定NRC时才需要填充代码。实际配置中主要涉及的模块有DCM,BSWM,ComM,RTE.2.BswM模块的配置。3.ComM模块的配置。1.DCM模块的配置。

Forever_Oct的博客 3086

java实现懒加载_用懒加载等函数式思想重构Java的初始化

假设有一个简单的程序来管理存储在本地文件系统上的某些文件的元数据,用户可从磁盘读取这些文件并以某种方式处理它们。管理文件元数据的类:@Setter@Getterpublic class DataFileMetadata {private long customerId;private String type;private File f;private String contents;public...

weixin_39971435的博客 346

大模型多智能体协作面试题及参考答案

在多智能体系统里,代理定义自身目标或效用函数的过程与系统架构、应用场景紧密相关。从本质上讲,目标是代理行为的导向,而效用函数则是对目标达成程度的量化评估。代理通常依据自身角色、系统全局需求以及与其他代理的交互关系来确立目标。比如在合作型 MAS 中,代理目标可能需要与全局目标对齐,像多个物流机器人协作完成货物配送时,每个机器人的目标会围绕 “高效完成分配任务”“避免路径冲突” 等展开,其效用函数可能涉及任务完成时间、能耗等指标的加权求和。目标定义的方式存在多种类型。

大模型大数据攻城狮的专栏 1022

java实现懒加载_java单例模式-懒加载

单例模式-我们经常都在使用,以下是懒加载的两种实现方式,仅当学习!方案一:synchronizedprivate static SingletonLazy instance = null;private SingletonLazy(){};public static SingletonLazy getInstance(){if (null == instance){createInstance(...

weixin_39645019的博客 721

从原理到落地:监控 SAP OData bgRFC 队列的全景实践指南

摘要(150字) 本文系统讲解SAP Gateway/Backend场景中bgRFC队列的监控方法。内容涵盖:1)监控必要性——确保异步可靠传输,及时识别失败消息;2)两种服务质量(EO/EOIO)对监控策略的影响;3)通过事务码SBGRFCMON和SPRO路径访问监控界面;4)关键授权S_BGRFC的配置要求;5)详细操作指南包括筛选条件和动作选项;6)标准巡检脚本;7)三个典型案例(认证错误、顺序阻塞、调度压力)的诊断与修复方案。全文提供完整的监控方法论和实战指导。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 284

Qt之自定义QToolTip,去掉显示动画和隐藏延时

先来看看Qt原生QToolTip的缺点:1.当提示内容无变化时,弹窗无法移动。只能先传个空字符串强制弹窗隐藏,然后在新位置再传个字符串。2.默认显示10多秒才消失,当然这个时间是可以设置的,但是如果我想一直显示呢?总不能设置一个超级大的时间吧。3.鼠标移出控件后(调用QToolTip::showText时传入了控件指针)默认300毫秒弹窗才隐藏。而且这个时间没法设置,如果想立即隐藏就没办法了。

草上爬的博客 4268

Java对图片懒加载_记录基于promise实现图片懒加载优化性能

一、场景项目最近要求对视频进行截图保存、查看,由于项目是公安方面的,导致一天一个控制台会生成很多图片,查看肇事图片的时候,页面一次加载过多导致全部渲染速度很慢,体验不好,于是基于网上现有资料和自己的实践,总结了在项目中的应用。二、实现过程1、首先先给img标签src 赋值为loading图片地址,然后添加一个真实要get的图片地址像下面一样src="./image/loading.jpg"alt=...

weixin_34061241的博客 403

多层环境室内定位系统综述总结

本文是一篇发表于2025年《IEEE Access》期刊的综述论文,由埃及开罗美国大学与卡塔尔卡内基梅隆大学团队合作完成,聚焦多层环境室内定位系统的核心挑战、技术方案及未来方向,填补了该领域缺乏全面综述的空白。

程序员石磊 439

java实现懒加载_Java 单例模式:懒加载(延迟加载)和即时加载

引言在开发中,如果某个实例的创建需要消耗很多系统资源,那么我们通常会使用惰性加载机制(或懒加载、延时加载),也就是说只有当使用到这个实例的时候才会创建这个实例,这个好处在单例模式中得到了广泛应用。这个机制在单线程环境下的实现非常简单,然而在多线程环境下却存在隐患。1、单例模式的惰性加载通常当我们设计一个单例类的时候,会在类的内部构造这个类(通过构造函数,或者在定义处直接创建),并对外提供一个sta...

weixin_39780260的博客 907

[QMT量化交易小白入门]-四十九、中小盘策略是否还有未来,市值再平衡策略,年化收益率124%

该策略旨在通过定期再平衡持仓,保持投资组合中股票数量恒定(),并优先持有市值较小的股票。具体来说,策略每两天(period = 2)进行一次再平衡,根据当前市值对持仓进行调整,以实现微盘股的投资目标。中小市值策略对资金量要求有限制,资金量太大由于流动性不足,滑点可能较大,资金量太小,可能不能达到10-20只持仓,来分散风险,10-100w可能是比较理想的,后续可以根据波动率动态调仓,或波动率大于一定值时触发再平衡加入ROE或其他财务指标,或者研发投入强度大的专精特新企业,进行组合优化。

木头大左的博客 1181

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java 中懒加载的正确实现方式

1.通常懒加载初始化的典型实现方式: public class LazyInit { public static Resource resource; public static Resource getResource() { if (resource == null) { resource = new Resource(); ...

无常的专栏 2万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java实现懒加载_Mybatis懒加载的实现

因为通过javassist和cglib代理实现的,所以说到底最主要的就是JavasisstProxyFactory类中的invoke方法和里面的load方法。其实读一读,里面的逻辑就是跟配置中定义的规则一样的因为github上的mybatis中文版中这部分注释比较少,所以从网上寻找博客,截取了代码注释片段记录下。JavasisstProxyFactorypublic class Javassist...

weixin_39559333的博客 339

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Java6实现pdf预览+懒加载

【代码】Java6实现pdf预览+懒加载。

weixin_44702386的博客 221

java实现懒加载_Fragment懒加载实现方案及原理

懒加载,又可称为延迟加载。目标与预加载正好相反,实现页面可见后再加载数据。看官们可根据自身业务需求自行斟酌常见的应用情景:如ViewPager内包含Fragment结构,需要在Fragment被展示之后再去加载数据。而通常我们用的ViewPager,配合FragmentPagerAdapter会默认实现预加载,就是在我们还没看见第一页以后的页面时,后面的页面就已经在加载数据了。那我们现在要做相反的...

weixin_30348133的博客 770

java实现懒加载_懒加载的实现以及优化(函数节流)

var throttle = function (fn, interval){var _self = fn, timer, firstTime = true;return function(){var args = arguments, _me = this;if(firstTime){_self.apply(_me, args);return firstTime = false;}if(time...

weixin_39976951的博客 695
上一篇: 惊艳!阿里自爆用600页讲清楚了44种微服务架构设计模式
下一篇: 阿里p8大白话讲解Spring Cloud微服务架构体系,小白看完秒变大神
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值