Java的单例设计模式详解

小编 2026-06-17 阅读:1593 评论:0
1.什么是单例模式 生成一个独一无二的,保证任何时刻一个类只有一个实例的模式 确保一个类只有一个实例,并提供一个全局访问点 可以在需要时才创建对象,避免了全局变量在程序启动时就得创建对象的缺...

1.什么是单例模式

  • 生成一个独一无二的,保证任何时刻一个类只有一个实例的模式
  • 确保一个类只有一个实例,并提供一个全局访问点
  • 可以在需要时才创建对象,避免了全局变量在程序启动时就得创建对象的缺点。

2.经典单例模式实现

public class MyInstance{
 //第一步:私有化构造器,只有类自身才能调用构造器外部类不能够直接new出这个类的实例对象
 private MyInstance(){}
 //第二步:声明一个全局静态变量来记录自身实例的对象,也是私有的,限制其它外部类访问
 private static MyInstance myInstance;
 //第三步:提供一个外部可访问的静态公开方法,来获得该类的唯一实例
 public static MyInstance getMyInstance(){
 //第四步:进行判断自身类对象如果为空,则创建一个实例
 if(myInstance==null){
  //这里的方法只执行了一次,生成了一个唯一的类对象
  myInstance=new MyInstance();
 }
 //第五步:如果不为空,则返回该类对象,故由始至终,该类对象只初始化过一次,只有一个对象存在,这就是单例模式
 return myInstance;
 }
}

3.经典模式存在的缺陷

这种经典模式也称之为懒汉式单例模式(lazy instantiaze),因为它是延迟化实例化的,即如果我们不需要这个实例,则它永远不会被初始化,只有在调用过一次实例化方法后,才会被创建出对象。

在多线程的情况下可能会产生并发问题,因为获取单例的方法getMyInstance()有可能被多个线程同时访问,这时就会有可能 创建出两个以上的实例对象。这就要考虑要线程安全的问题了,解决问题就是在获取实例方法处加一个同步锁,这样就能轻松地解决线程并发的问题了。

public static synchronized MyInstance getMyInstance(){
 //加同步锁关键字synchronized,这样在有线程访问这个方法时,其它线程只能等待当前线程访问结束才能访问这个方法。
 if(myInstance==null){
  //这里的方法只执行了一次,生成了一个唯一的类对象
  myInstance=new MyInstance();
 }

4.多线程下同步所造成的性能问题

如果将获取实例的方法进行同步的话,会造成程序执行的效率大大地下降,而且单例对象生成只要调用一次方法即可,之后每次调用这个方法时,同步都是一种累缀,有可能会拖垮程序的性能。

当然如果你的程序对于性能的要求并不是很高的话,用同步的方法获取单例是最简单而有效的。

为保证程序的性能并且又不会出现并发的问题,可以使用另一种生成单例对象的模式,叫做饿汉式单例模式(eagerly instantiaze)

public class MyInstance{
 //第一步:私有化构造器
 private MyInstance(){}
 //第二步:声明一个全局静态变量来记录自身实例的对象,并进行实例化
 private static MyInstance myInstance=new MyInstance();
 //第三步:提供一个外部可访问的静态公开方法,来获得该类的唯一实例
 public static MyInstance getMyInstance(){
 return myInstance;
 }

这个模式使JVM在加载这个类时会马上创建唯一的单例对象,这样就能保证任何线程访问静态单例变量myInstance时,单例对象一定被实例化过了。

5.利用双重检查加锁来提升性能

  • 首先检查实例是否已经创建了,如果没有才进行同步获取实例的方法,这样就保证了实例方法只会在第一次获取实例时会同步。
  • 这里要用到一个关键字volatile,此关键字确保了当实例变量myInstance被初始化成实例对象时,多个线程能正确地处理实例变量。注意,这个关键字只有在Java1.5及以上的版本才会对双重检查加载生效。
public class MyInstance{
 //用关键字volatile修饰实例变量
 private volatile static MyInstance myInstance;
 //私有化构造器
 private MyInstance(){}
 public static MyInstance getMyInstance(){
 //第一次检查实例是否存在
 if(myInstance==null){
  //如果不存在则进入同步区块
  synchronized (MyInstance.class){
  if(myInstance==null){
   //第二次检查,如果不为空才真正创建实例对象
   myInstance=new MyInstance();
  }
  } 
 }
 //如果不为空,则直接返回该类对象
 return myInstance;
 }
}

单例模式的所有情况都已经总结完毕,一开始以为单例模式应该是所有设计模式中最简单易懂的了,没想到看到四人帮的HeadFirst设计模式后发现还有这么多门道,真的是学无止境。

注:以上所有内容皆总结自《HeadFirst 设计模式》

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

上一篇:mysql导入excel数据 下一篇:jpush推送
热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表