前记

昨天学妹抱怨专业课中的java 23个设计模式。她问:23个设计模式越看越扎心,尤其是单例模式,有没有什么破解之法。我告诉她 java 23个设计模式看上去多,要挑知识重点并结合程序实例来记忆,尤其是学习之后自己动手写一个设计模式,很容易能掌握。我给她讲解了如何去学习单例模式。最后她哈哈大笑,“我懂了”。

对于java 23个设计模式,每个刚接触的人都可能觉得设计模式太多了而萌生不想学习的念头,特别是第一次接触的时候。于是我写这篇文章,用最通俗易懂的语言讲解单例模式,帮助大家理解。

文章的标题只是噱头,作为热爱交流技术的学习者,我们应该脚踏实地,所以我会保证文章的内容都是干货!

适用场景

一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化。比如windows系统的回收站是单例模式,打开一个回收站,关闭后再打开一个回收站,前后两个回收站是一样的。

饿汉式

主动创建实例的私有静态引用。调用前单例已经存在。

优点:简单方便,线程安全

缺点:如果没有调用该实例对象,则造成内存资源浪费

public class Singleton1 {//饿汉模式,天然线程安全// 指向自己实例的私有静态引用,主动创建private static Singleton1 singleton1 = new Singleton1();// 私有的构造方法private Singleton1(){}// 以自己实例为返回值的静态的公有方法,静态工厂方法public static Singleton1 getSingleton1(){return singleton1;}
}

懒汉式

调用时创建实例对象。只有调用时,才去初始化单例。

优点:简单方便,不使用时不创建对象

缺点:线程不安全,多个线程的情况下,如果一个线程符合判断条件,另一个线程也进入条件,可能产生多个实例对象

public class Singleton2 {//懒汉式private static Singleton2 singleton2;private Singleton2(){}public static Singleton2 getSingleton2(){if(singleton2 == null){singleton2 = new Singleton2();}return singleton2;}}

单锁模式

使用sychronized修饰getSingleton()方法

优点:线程安全

缺点:粗粒度,对程序的性能影响大

public class Singleton4 {private static Singleton4 singleton4 = null;private Singleton4(){}public static synchronized Singleton4 getSingleton4() {if(singleton4 == null){singleton4 = new Singleton4();}return singleton4;}
}

双重加锁判断

创建一个静态锁,并且使用两个if判断

优点:线程安全,保证了程序的性能,并且节约了资源

public class Singleton3 {//程序运行时创建一个静态只读的进程辅助锁private static Object syncRoot = new Object();private static Singleton3 singleton3;private Singleton3(){}public static Singleton3 getSingleton3() {if(singleton3 == null){//先判断是否存在synchronized (syncRoot){if(singleton3 == null){singleton3 = new Singleton3();}}}return singleton3;}
}

静态内部类

优点:既实现了线程安全,又避免了同步机制带来的性能影响

public class Singleton6 {private static class LazyHolder{private static final Singleton6 singleton6 = new Singleton6();}private Singleton6(){}public static final Singleton6 getSingleton6(){return LazyHolder.singleton6;}
}

登记式

维护了一组单例类的实例,将这些实例放在一个Map中,对于已经登记过的实例,则从Map直接返回,没有登记过的则先登记,后返回。

import java.util.HashMap;
import java.util.Map;public class Singleton5 {private static Map<String,Singleton5>map = new HashMap<>();static {Singleton5 singleton5 = new Singleton5();map.put(singleton5.getClass().getName(),singleton5);}private Singleton5(){}public static Singleton5 getSingleton5(String name){if(name == null){name = Singleton5.class.getName();}if(map.get(name) == null){try {map.put(name,(Singleton5) Class.forName(name).newInstance());} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}return map.get(name);}
}

单例模式优缺点

优点

  1. 节省内存空间,在内存中只有一个对象

  2. 减少了系统的性能开销

  • 例如一个对象需要许多资源时,比如读取配置,产生其他依赖的对象。在应用启动时直接产生一个实例对象。
  1. 避免对资源的多重占用
  • 比如写文件,因为只有一个实例,避免对同一个文件同时写操作。
  1. 可以在系统设置全局的访问点,优化和共享资源访问。
  • 例如设计一个单例,负责系统内所有数据表的处理。

缺点

  1. 单例模式一般没有接口,扩展比较困难,除非修改代码。

  2. 单例对象如果持有Context,那么很容易引发内存泄露。

总结

单例模式是java 23种设计模式之一。单例模式适用于对象需要被频繁地创建销毁并且性能无法优化的场景。

本文介绍了单例模式中的饿汉式、懒汉式和登记式。其中饿汉式与懒汉式需要重点学习和理解。饿汉式是天然线程安全,而懒汉式线程不安全,所以引出了懒汉式的单锁模式、双重加锁判断和静态内部类

学妹问单例模式,我用最通俗易懂的讲解让她学会了相关推荐

  1. 学妹问我Java枚举类与注解,我直接用这个搞定她!

    很多人问我学妹长什么样,不多说 上图吧! 学妹问我Java枚举类与注解,我直接一篇文章搞定! 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举 ...

  2. 【熬夜猛肝万字博文】学妹问我怎么入门 Javascript,百般盘问下我终于决定贡献出自己的 JavaScript入门笔记(三)

    你好,我是阿ken?? 版权声明:本文为CSDN博主「」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 另外,博文中某些图片或内容可能出自网络,如有侵权或问题,请及 ...

  3. 学妹问H哥:你是如何平衡工作和生活的?

    作者 l Hollis 来源 l Hollis(ID:hollischuang) 这几天被B站的<后浪>刷屏了,不管别人怎么看,我个人觉得还挺不错的.很多人说<后浪>传达出一种 ...

  4. python记忆口诀-学妹问我: 如何提高编程能力

    聊天截图 聊天截图 前言 开局两张图,剩下全靠吹了. 上面这两张图便是写这篇文章的原由. 对话框的另一边,是一位大二计算机科班在读的小姐姐,看似平静的文字背后透露着迷茫与困惑,还对未来的焦虑. 透过屏 ...

  5. python记忆口诀-学妹问我:如何提高编程能力

    聊天截图 聊天截图前言 开局两张图,剩下全靠吹了. 上面这两张图便是写这篇文章的原由. 对话框的另一边,是一位大二计算机科班在读的小姐姐,看似平静的文字背后透露着迷茫与困惑,还对未来的焦虑. 透过屏幕 ...

  6. 学妹问我:怎么从网页下载所有图片?我答:天机不可泄露

    @Author:Runsen 最近,有一个学妹关注我,想让我帮她把一个网页的所有图片下载下来. 正所谓,私信找我,那是看得起我,虽然不知道是男还是女,这不,我就解决了这个简单的问题. 如果您曾经想在某 ...

  7. 学妹问的Spring Bean常用配置,我用最通俗易懂的讲解让她学会了

    你好呀,我是沉默王二,一枚有趣的程序员,写的文章一直充满灵气,力求清新脱俗.昨天跑去王府井的小米店订购了一台小米 10,说是一周之内能到货,但我还是忍不住今天就想见到她.见我茶不思饭不想的,老婆就劝我 ...

  8. 【熬夜猛肝万字博文】学妹问我怎么入门 Javascript,百般盘问下我终于决定贡献出自己的 JavaScript入门笔记(二)

    你好,我是阿ken?? 版权声明:本文为CSDN博主「」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 另外,博文中某些图片或内容可能出自网络,如有侵权或问题,请及 ...

  9. 学妹问,学网站开发还是打 ACM?

    聊聊我的选择 大家好,我是鱼皮,前几天看到一位大一计科同学的问题:我想学做 Web 项目,又想学算法搞 ACM,如何取舍呢 ? ACM 是国际大学生程序设计竞赛,旨在展示大学生创新能力.团队精神.编写 ...

最新文章

  1. PyTorch中的Element-wise operations
  2. Tomcat配置Web虚拟目录
  3. MVC站点默认页为html页,设置ASP.NET MVC站点默认页为html页
  4. saml java实现_java-saml
  5. 贪心算法(Greedy Algorithm)之霍夫曼编码
  6. k2pdfopt教程
  7. jinja Escaping
  8. Chrome development tools学习笔记(3)
  9. mysql 优化 (1)
  10. 翻译:swift 5通过使用泛型进行高级异步操作Operation
  11. linux触摸屏应用程序开发,linux触摸屏(一)编写触摸屏应用
  12. 怎么用python学习网站开发_2018年最好用的5个python网站开发框架
  13. OpenDDS开发人员指南中文版3.23(2)入门
  14. OPCUA协议: 复杂服务器C语言初步实践(回调与方法)
  15. 家用洗地机有什么优缺点?入门级家用洗地机
  16. js 获取汉字首拼和全拼和拼音
  17. Servlet的工作原理简介
  18. Shell语法详解专栏目录
  19. react-router v4 路由改变页面不刷新
  20. 即构CEO林友尧:让实时音视频技术融于无形

热门文章

  1. 东芝笔记本自带蓝牙在ubuntu中的驱动问题修复方法
  2. 关于中国的夏令时转换
  3. 观察验证交换机工作原理
  4. FFmpeg 合并了对 JPEG-XL 图像格式的支持
  5. Spire.Office.NET Platinum(Hotfix) Version:7.7.2
  6. x64 编译 静态链接_C++静态库与动态库
  7. 计算机网络(三):网络层
  8. Passbook Test
  9. 实践两年多的新零售,谁会掉队,谁会脱颖而出?
  10. linux怎么做路由跟踪_Linux 路由追踪命令:traceroute