单例模式

单例模式

定义

一个类有且仅有一个实例,并且自行实例化向整个系统提供。(创建型模式)设计模式中比较简单的几种之一,单例模式就是让一个类在系统运行过程中只会产生唯一的一个实例,单例模式主要:

  1. 单例类只能有一个实例。
  2. 单例类必须自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

使用场景

  • 需要频繁实例化然后销毁的对象。
  • 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  • 有状态的工具类对象。
  • 频繁访问数据库或文件的对象。

单例模式的实现

单例模式的实现一般根据实例化对象时的不同分为懒汉式和饿汉式.

懒汉式典型实现

package factory.pattern.singleton;
/**
 * Created by fk5431 on 6/19/17.
 */
public class SingletonLazy {
    private static SingletonLazy singletonLazy;
    private SingletonLazy (){}
    public static SingletonLazy getInstance(){
        if( singletonLazy == null){
            singletonLazy = new SingletonLazy();
        }
        return singletonLazy;
    }
}

懒汉式的模式就是在需要进行实例化的时候在进行实例化,这种方式在多线程的时候是有问题的,会有线程安全问题.

懒汉式线程安全形式

package factory.pattern.singleton;
/**
 * Created by fk5431 on 6/19/17.
 */
public class SingletonLazeSafe {
    private static SingletonLazeSafe singletonLazeSafe;
    private SingletonLazeSafe(){}
    public static synchronized SingletonLazeSafe getInstance(){
        if(singletonLazeSafe == null){
            singletonLazeSafe = new SingletonLazeSafe();
        }
        return singletonLazeSafe;
    }
}

懒汉式的线程安全模式在进入获取实例方法时候就会加synchronize,可以保证线程安全获取唯一的实例,但是如果该方法调用过多会有性能方面的影响.

饿汉式

package factory.pattern.singleton;
/**
 * Created by fk5431 on 6/19/17.
 */
public class SingletonHungary {
    private static SingletonHungary singletonHungary = new SingletonHungary();
    private SingletonHungary(){}
    public static SingletonHungary getInstance(){
        return singletonHungary;
    }
}

饿汉式会在类装载时候就进行实例的初始化,虽然没有了synchronize的效率影响,但是在类加载的时候就进行了初始化一方面浪费了内存,也没有实现lazy loading加载的效果.

双重校验锁

package factory.pattern.singleton;
/**
 * Created by fk5431 on 6/19/17.
 */
public class DoubleCheckedLocking {
    private static DoubleCheckedLocking doubleCheckedLocking;
    private DoubleCheckedLocking(){}
    public DoubleCheckedLocking getInstance(){
        if(doubleCheckedLocking == null){
            synchronized (DoubleCheckedLocking.class){
                if(doubleCheckedLocking == null){
                    doubleCheckedLocking = new DoubleCheckedLocking();
                }
            }
        }
        return doubleCheckedLocking;
    }
}

这种方式采用了双锁机制,一方面保证了多线程的安全,另一方面还提高了效率.但是看起来是完美,但是实际上这种方式是有缺陷的,是错误的一种.(双重检查锁定的问题下次专门写个文章)

静态内部类

package factory.pattern.singleton;
/**
 * Created by fk5431 on 6/19/17.
 */
public class SingletonStaticClass {
    //静态内部类
    private static class SingletonHodler{
        private static final SingletonStaticClass INSTANCE = new SingletonStaticClass();
    }
    private SingletonStaticClass(){}
    public static final SingletonStaticClass getInstance(){
        return SingletonHodler.INSTANCE;
    }
}

这种方式利用了 classloder 机制来保证初始化 instance 时只有一个线程,但是这个是类装载的时候不一定会进行初始化,只有在调用 getInstance 方法时候才会显示的装载SingletonHodler,然后实例化instance.

枚举的方式

public enum EnumSingleton {
    INSTANCE;
}

枚举的方式最简单,又是线程安全的(默认枚举实例的创建是线程安全的)

#设计模式#
设计模式介绍 文章被收录于专栏

设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。其实就是经过前人反复使用总结使用得出在不同场景有对应的解决方案。

全部评论

相关推荐

理想汽车前瞻硬件研发面经分享面试背景bg双非一本 有两段大厂实习经历干的基本是测试+研发一面技术面(1.5h)全程无八股,聚焦项目细节深挖,节奏紧凑但交流顺畅。1. 自我介绍(重点突出半导体+电子技术双背景、竞赛获奖及核心项目经历);2. 实习工艺优化的核心难点是什么?测试方案3.项目改进点4. 本科期间参与的项目和竞赛中,你觉得自己收获最大的能力是什么?5. 项目中遇到过哪些实验数据与预期不符的情况?怎么解决的?6.半导体器件可靠性测试中 是如何进行故障定位和参数优化的7. 为什么选择自主搭建硬件平台而非用现成开发板?8.场景题输出调控报告9.手撕代码10.为什么要干硬件而不是嵌入式软件反问环节1. 若入职,会具体负责哪类产品的研发2. 工作中是否有机会深度参与核心参数优化、故障归因这类一线研发工作?压力强度如何?3.团队在器件选型、原理图设计方面有哪些规范或经验沉淀?涵盖产品需求分析、可行性报告撰写、硬件系统方案设计、EMC认证、功能安全设计、器件选型、原理图设计、工艺优化及单板调试,有专门团队负责,与我的技能匹配度很高。后续流程需等待HR面安排。二面HR面(40min)1. 自我介绍(突出协作能力和项目成果);2. 分享一下实习时,最具挑战性的任务是什么?怎么完成的?3. 未来3-5年的职业规划是什么?希望在硬件领域往哪个细分方向深耕?4.并没有那么匹配的研发经历如何胜任工作5. 竞赛的心路历程6. 你是如何在项目中提升团队凝聚力的?举一个具体例子。7. 到岗日期及实习时间反问环节1.公司针对实习生有哪些职业发展路径?是否有技术晋升或跨项目学习的机会?2.公司规模及构成已offer
查看20道真题和解析
点赞 评论 收藏
分享
2025-11-25 15:37
门头沟学院 Java
自我介绍+项目拷打八股:JDK动态代理和CGLib代理的区别是什么?两种代理的优缺点是什么?两种代理的应用场景是什么?高并发场景下,如何安全地更新一个计数器?悲观锁有哪些具体实现的类?乐观锁有哪些具体实现的类?AtomicInteger 是什么?(不会)synchronized、Atomic、Lock 它们的实现方式具体有什么区别?synchronized 有什么优缺点?synchronized 一般在哪些场景下比较适用?Java 里面内存泄漏和内存溢出这两个概念有什么区别?内存泄漏有哪些典型的例子?一般用什么工具去检测出内存泄漏的场景?如何开启内存泄漏检测?通过什么命令或者说是什么工具?实现深拷贝要怎么做?Java 里面创建线程的方式有哪一些?各种创建线程方式的优缺点是什么?线程池的工作原理是什么?描述一下提交任务时,线程池是怎么决定使用核心线程、阻塞队列还是非核心线程的?Spring Boot 的自动配置机制是怎么实现的?@Conditional 注解是如何确保配置是按需加载的?什么是 SQL 注入?怎么去避免 SQL 注入?查看 CPU 的使用情况用什么 Linux 命令?查看内存的使用情况用什么 Linux 命令?查看日志一般用什么 Linux 命令?实时查看日志的话,tail 命令后面要加什么参数?查看日志最后 500 行的命令怎么写?查看某个关键字对应的日志用什么命令?设计模式用的多吗?用了哪些?策略模式和工厂模式是怎么实现的?具体应用场景是什么?什么情况下会使用单例模式?单例模式的使用场景是什么?
发面经攒人品
点赞 评论 收藏
分享
2025-11-27 22:23
已编辑
百度_前端(实习员工)
【11.21 百度一面】:1:自我介绍2:小程序项目介绍(面试官比较感兴趣这个)3:实习项目简单问了一下4:可视化5:大文件上传整体的思路、断点续传具体怎么实现?6:讲一下transform怎么使用的(提到小程序里面的一个应用)7:react常见hook8:父组件A里面有一个子组件B,子组件B使用useMemo()缓存值,如果A重新渲染,会导致B中useMemo重新计算嘛?        (回答:分情况,要是缓存的值中有父组件传递的props就还是要)9:无限滚动加载和图片懒加载10:拦截器主要做了些什么工作?11:数组常用方法?12:你做了可视化大屏展示,现在有多个大屏,怎么适配各种尺寸呢?(答了媒体查询,为每一个尺寸范围适配不同的比例大小)追问:如果提前不知道大屏的宽度呢答:可以使用flex响应式布局,比如flex 1 自动填充剩下的内容区域13:说一下事件冒泡是什么,怎么阻止冒泡(用e.stopPropagation())14:手搓 轮播图(太久没有写react了,面试官一直耐心指导,最后还是没搓出来,说了一下实现原理)15:反问业务、技术栈、实习生培养方案一面的面试官真的超级好,就我面试以来(七牛云、金蝶、懂车帝)是最好的一个了。一点一点指导,面试用的“如流”这个软件,中间断联了两次(一次网络断开,一次电脑没电直接关机,人傻了直接),结果面试官一点都没生气,还是很耐心的讲面完,10分钟不到,发消息,约二面...【11.24 百度二面】1:自我介绍2:Promise哪些常用方法3:大文件上传4:手写Promise.all (有一点点小缺憾)5:懒加载怎么实现的 (IntersationObserver)6:react的懒加载怎么实现(同上 + React.lazy结合Suspense)7:react常用hook8:useCallback和useMemo说一下9:手撕一个react自定义hook:getPrevieusValue(value) 传入一个值(state),获取他上一次的状态值(用的是map+数组存)面试官:其实可以用ref,因为你现在这个实现的话,依照的是状态,万一不小心改变了状态可能导致页面重新渲染8:3s后页面上显示啥?为啥?const app = () => {const [count, setCount] = useState(0)const [countTime, setCountTime] = useState(0)useEffect(() => {let timer = setTimeout(() => {setCountTime(count)}, 3000)setCount(5);() => clearTimeout(timer)}, [])return (<div>count:{{ count }}countTime:{{ countTime }}</div>)}(答了:分别是5和0,因为react状态是一个快照,他每计算次依照的是当前这一刻的状态(还好之前看过官方文档))9:上一个问题,那我想让都显示5怎么办?(提到用函数式更新、flushAsync、Ref持久化绑定)面试官:也可以在useEffect依赖里面加 count10:redux使用过嘛? 了解过基于redux开发的第三方工具嘛?(不了解)11:为啥使用redux不用useContext呢?12:说一下小程序的分包机制和分包预加载13:手写:数组转成树结构(没写出来[我算法太弱了[苦涩]],说了思路,用递归)const a = [{id: 1, parent: null, name: 'Big'},{id: 2, parent: 3, name: 'hello'},{id: 3, parent: 1, name: 'aloha'},{id: 4, parent: 1, name : 'yes'}];const b = {id: 1,name: 'big',children: [{id: 3,name: 'aloha',children: [{id: 2,name: 'hello',children: null,},],},{id: 4,name: 'yes',children: null,},],};面试官说你思路没问题,然后就给我讲了一遍非递归的实现思路如流这个软件,不知道是不是不适配我的电脑还是啥,面试的时候一直掉线(掉了四五次),开始我还以为我的网有问题,不过好在面试官没有生气,而且手撕题还给我耐心纠错和指导,也是很好的一个面试官【11.27】hr电话正上体育课,刚测完1000m,累成憨憨了,摊在地上结果忽然收到hr的电话,oc,下午1点多快到2点的时候,收到正式offer邮件......【插话】本来二面结束(周一),感觉没戏了,周二到周四整个人都是一个将die的状态,浑身不舒服,也没胃口,觉也睡不好,期间还面了懂车帝、深圳锐明技术,懂车帝面成粑粑了、锐明面的很好,但是这俩截至目前都没有下文面试,运气真的很重要,要是遇到一个恶心人的面试官,神来了也得挂。唯一 一点幸运的是,我做过小程序,刚好和他们组技术栈和业务匹配,同时干小程序的人本身也不多,所以被面试官看上了吧,要是投的其他业务组,一面都得挂
发面经攒人品
点赞 评论 收藏
分享
评论
6
14
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务