本文转载自:java单例模式——详解JAVA单例模式及8种实现方式_EatingSoilLang的博客-CSDN博客_java单例模式

## 单例模式是最简单也是最基础的设计模式之一,下边一起学习一下单例模式!

一.单例模式的定义:
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。

二.单例模式的特点
 1、单例类只能有一个实例。
 2、单例类必须自己创建自己的唯一实例。
 3、单例类必须给所有其他对象提供这一实例。
单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性。

三.线程安全问题:
一方面在获取单例的时候,要保证不能产生多个实例对象,后面会详细讲到五种实现方式;
另一方面,在使用单例对象的时候,要注意单例对象内的实例变量是会被多线程共享的,推荐使用无状态的对象,不会因为多个线程的交替调度而破坏自身状态导致线程安全问题,比如我们常用的VO,DTO等(局部变量是在用户栈中的,而且用户栈本身就是线程私有的内存区域,所以不存在线程安全问题)。

四.实现单例模式的八种方式:
1.饿汉式(静态常量)【可用】
优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

2.饿汉式(静态代码块)【可用】
这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的。

3.懒汉式(线程不安全)【不可用】
这种写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。


4.懒汉式(线程安全,同步方法)【不推荐用】
解决上面第三种实现方式的线程不安全问题,做个线程同步就可以了,于是就对getInstance()方法进行了线程同步。
缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。

 
5.懒汉式(线程安全,同步代码块)【不可用】
由于第四种实现方式同步效率太低,所以摒弃同步方法,改为同步产生实例化的的代码块。但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。


6.双重检查【推荐使用】
Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。
优点:线程安全;延迟加载;效率较高。


7.静态内部类【推荐使用】
这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。
类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
优点:避免了线程不安全,延迟加载,效率高。


8.枚举【推荐使用】
借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

五.单例模式的优点
系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
六.单例模式的缺点
当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其他开发人员造成困扰,特别是看不到源码的时候。
七.单例模式的使用场景
• 需要频繁的进行创建和销毁的对象;
• 创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
• 工具类对象;
• 频繁访问数据库或文件的对象。

java单例模式——详解JAVA单例模式及8种实现方式相关推荐

  1. 【java】详解Java的类文件(class文件)结构

    1.概述 转载:详解Java的类文件(class文件)结构 大家好,我是二哥呀,今天我拿了一把小刀,准备解剖一下 Java 的 class 文件. CS 的世界里流行着这么一句话,"计算机科 ...

  2. java deepcopy_详解JAVA 深层拷贝 DeepCopy的使用方式

    说到复制方法,在开发程序中要怎么复制呢?其实复制Java数组的方法很多,但大多数都是浅层复制,今天爱站技术频道小编带你寻找详解JAVA 深层拷贝 DeepCopy的使用方式. 方法实现很简单,提供两种 ...

  3. java命令详解 java -D

    2019独角兽企业重金招聘Python工程师标准>>> JAVA 命令参数详解: 1.-D<name>=<value> set a system proper ...

  4. java nio详解,Java NIO API详解

    Java NIO API详解 在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞(blocking)API.对于大多数应用来说,这样的API使用很方 便,然而,一些对 ...

  5. java jdbc_详解Java基础知识——JDBC

    JDBC Java DataBase Connectivity,java数据库连接,为了降低操作数据的难度,java提供jdbc,按照java面向对象特点,对操作进行了很多封装. JDBC提供了很多接 ...

  6. Java注释详解-Java文档注释生成Java API文档

    Java文档注释是一种功能强大的注释形式,如果在你所编写的程序中规范的添加文档注释,那你就可以生成一份系统正规的API文档.Java文档注释 /**文档注释内容*/,注意区分多行注释/*多行注释*/. ...

  7. 【java】详解java中的注解(Annotation)

    目录结构: contents structure [+] 什么是注解 为什么要使用注解 基本语法 4种基本元注解 重复注解 使用注解 运行时处理的注解 编译时处理的注解 1.什么是注解 用一个词就可以 ...

  8. java hgetall_详解Java使用Pipeline对Redis批量读写(hmsethgetall)

    一般情况下,Redis Client端发出一个请求后,通常会阻塞并等待Redis服务端处理,Redis服务端处理完后请求命令后会将结果通过响应报文返回给Client. 感觉这有点类似于HBase的Sc ...

  9. java cache详解,Java内存缓存详解

    1.缓存为什么要存在 应用服务器资源是有限的,数据库每秒中接受请求的次数也是有限的.如果利用有限的资源来提供尽可能大的吞吐量呢,一个办法:减少计 算量,缩短请求流程(减少网络io或者硬盘io),这时候 ...

  10. byte java byte_详解java中的byte类型

    Java中整数类型有:byte占8位, short 占16位, int占32位, long占64位 Java也提供了一个byte数据类型,并且是基本类型中的整数类型.java byte是作为最小的数字 ...

最新文章

  1. linux网络驱动架构,Linux网络体系架构和网卡驱动设计
  2. ADSL的PPPOE拨号客户端上的ppp authentication pap “callin”的正确理解
  3. 世界上将出现一种新职业
  4. pku1182(食物链) hdu3047 Zjnu Stadium
  5. “女性机器人”火了,称其只有富人买得起,男性用户表示很满意
  6. el表达式的语法_「手把手教python3接口自动化」「第三章」:Python3 语法
  7. HTML5_1 笔记
  8. STL vector用法介绍
  9. Android 8.0 学习(3)---Android Treble
  10. 云计算年度技术盛典,腾讯Techo Park开发者大会将在京召开
  11. 1114. Family Property (25)-PAT甲级真题(并查集)
  12. 微信公众号二维码在哪里看?如何查看自己的微信公众号二维码?
  13. 时间开关的工作原理、安装方法及其应用特点
  14. 我用php构建了魔兽世界服务器,只为证明php是世界上最好的语言
  15. mysql 学习指南
  16. STM32 USB 开发(二)HID Slave 通信 --- 简单上位机开发
  17. 敏捷项目管理的五个要素
  18. 淘宝新店没有生意如何推广和引流呢
  19. Verify the connector‘s configuration, identify and stop any process that‘s listening on port 8911
  20. 七个顶级心理寓言(看了受用一生)(转)

热门文章

  1. EnableViewState详细分析
  2. Odin WindowEditor使用体会
  3. 雨过天晴电脑保护系统 试用手记
  4. 003-电脑软件系统保护
  5. Apple Pay如何使用?全网最完美攻略(图文教程)!
  6. VC++设置默认音频设备(附源码)
  7. bash 运行可执行文件hello 报错 No such file or directory
  8. java编写简单聊天界面_java实现简单聊天室单人版
  9. [SUCTF 2018]GetShell
  10. 【分享】豆瓣上排名top100的书籍