首页 > 编程语言 >Java单例模式

Java单例模式

时间:2022-09-20 22:13:17浏览次数:57  
标签:Singleton Java private instance static 模式 单例 public

单例模式

  单例模式核心是保证一个类只有一个实例,并且提供一个访问实例的全局访问点。

使用场景

  需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)

  • Spring中bean对象的模式实现方式
  • servlet中每个servlet的实例
  • spring mvc和struts1框架中,控制器对象是单例模式
  • 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加
  • 操作系统的文件系统,也是大的单例模式实现的具体例子,一个操作系统只能有一个文件系统
  • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,每次new一个对象去读取。
  • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源
  • Windows的Task Manager(任务管理器)就是很典型的单例模式(这个很熟悉吧),想想看,是不是呢,你能打开两个windows task manager吗? 不信你自己试试看哦~
  • windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
  • 网站的计数器,一般也是采用单例模式实现,否则难以同步。
  • 应用程序的日志应用,一般都何用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  • Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。

单例模式优点

  单例模式保证了系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能

单例模式缺点

  扩展困难,滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

实现方式

懒汉模式(线程不安全)

是否 Lazy 初始化:是
是否多线程安全:否
描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
public class singleton { private static singleton instance; private singleton (){} public static singleton getInstance() { if (instance == null) { instance = new singleton(); } return instance; } }

懒汉模式(线程安全)

是否 Lazy 初始化:是
是否多线程安全:是
这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

饿汉模式

是否 Lazy 初始化:否
是否多线程安全:是
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloader 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }

饿汉模式(静态代码块)

1.在类加载的时候便完成了实例化.
2.在初始化的时候可以进行一些属性的初始化.
`
public class singleton2 {
private static final singleton2 SINGLETON_2;
int anInt;
static {
SINGLETON_2 = new singleton2(1);
}

private singleton2(int anInt) {
    this.anInt = anInt;
}

public static singleton2 getInstance() {
    return SINGLETON_2;
}

}
`

双检锁/双重校验锁

JDK 版本:JDK1.5 起
是否 Lazy 初始化:是
是否多线程安全:是
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }

静态内部类

是否 Lazy 初始化:是
是否多线程安全:是
public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }

标签:Singleton,Java,private,instance,static,模式,单例,public
From: https://www.cnblogs.com/todayiswendy/p/16711925.html

相关文章

  • Java面向对象初探
    Java面向对象1.类和对象1.1类和对象的概念:类是抽象的集合,对象是具体的实例。类可以想象为制作蛋糕的模具,对象就是做出来的蛋糕。类中包含属性(字段)和方法(操作)1.2类......
  • Java基础08 自增自减运算符、初识Math类
    publicstaticvoidmain(String[]args){//++--自增自减一元运算符inta=3;intb=a++;//执行完这行代码后,先给b赋值,再自......
  • java: Bridge Patterns
     /***版权所有2022涂聚文有限公司*许可信息查看:*描述:*桥梁模式BridgePatterns*历史版本:JDK14.02*2022-09-12创建者geovindu*2022-09-12......
  • Java基础07 基本运算符
    运算符◆Java语言支持如下运算符:算术运算符:+,-,*,/,%,++,-赋值运算符=关系运算符:>,<,>=,<=,==,!=instanceof逻辑运算符:&&,||,!位运算符:&,|,^,~,>>,<<,>>>了解......
  • java中如何将函数作为参数传递呢?
    函数简介:  函数(function)的定义通常分为传统定义和近代定义,函数的两个定义本质是相同的,只是叙述概念的出发点不同,传统定义是从运动变化的观点出发,而近代定义是从集合、......
  • Java基础知识,JDK8下载安装环境配置
    Java基础知识Java的三种版本JavaSE:标准版,主要用于开发桌面程序,控制台开发等等JavaME:嵌入式开发,主要用于开发手机,小家电等等,目前使用的比较少JavaEE:企业级开发,主......
  • java 根据任意List<Object>输出excel表格
    使用方法:将自定义的pojo类,添加到list中,直接调用输出类的out方法就可以(注意:这个pojo类的属性上必须使用自定义注解,index属性用来标识该属性放在哪一列,value则标示输出的中......
  • java异常笔记
    为什么会有异常计算机不是万能的,程序猿也不是万能的,总会犯错误。比如当我们编译时报错,或者代码能跑后出现数组越界这就会出现异常;异常有几种两种,一种是编译时异常,另......
  • JavalearnDay02
    变量表达式相关概念:(一)常量​ 概念:常量,在程序中运行过程中,值不能发生改变的量(数值).(二)计算机存储单元计算机存储设备的最小信息单元叫“位(bit)”,我们又称之为......
  • CSDN(markdown模式下)如何调整图片大小以及如何调整位置
    版权声明:本文为CSDN博主「圣喵」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/m0_66769266/article/details/1240......