前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【设计模式】之单例模式

【设计模式】之单例模式

作者头像
xcbeyond
发布2020-04-02 17:50:43
3480
发布2020-04-02 17:50:43
举报
文章被收录于专栏:技术那些事技术那些事
把几年前写的一些文章,今天与大家分享下,或许几年写的文章过于幼稚、浅显,但望勿喷。

单例模式是23种设计模式中最简单、最常见的一种,也是各个公司面试题中必考的设计模式之一,是程序猿必备掌握的。

单例模式(Singleton Pattern):

确保某个类只有一个对象。单例类的构造器是私有的(private),避免外界利用构造器直接创建出任意多的实例。由于构造器是private的,因此单例类是不能被继承。

特点:

1>、单例类只能有一个实例。

2>、单例类必须自己创建自己的唯一实例。

3>、单例类必须给所有其他对象提供这一实例。

单例模式,可以形象的比作"一山不容二虎",如:计算机系统中,我们只需要他有一个唯一的实例在工作。无论一个电脑连接了多少台打印机,但是它的后台处理程序只有一个唯一的实例在工作,这样才不会出现混乱的交错情况。

单例模式分三种:懒汉式单例饿汉式单例登记式单例三种。

1、饿汉式单例

是一种典型的空间换时间的方式,在类进行加载时,我们静态实例对象就完成了实例化操作。操作时因为加载时已经实例化过了,操作速度会变快。但是因为类加载时这个对象就已经存在了,它的生命周期较长,占用空间。

代码语言:javascript
复制
package 单例模式;
/**
 * 饿汉式单例:自己将自己实例化
 * 在这个类被加载时,静态变量instance会被初始化,此时类的私有构造器被调用,这时单例类的唯一实例就被创建了。
 * @author xcbeyond
 * @date 2012-5-1 上午11:56:26
 */
public class EagerSingleton {
  private static final EagerSingleton instance = new EagerSingleton();
  //私有构造器
  private EagerSingleton() {
  }
  
  public static EagerSingleton getInstance() {
    return instance;
  }
}

2、懒汉式单例

与饿汉式单例不同的是,懒汉式单例类在第一次被引用时将自己实例化。如果加载器是静态的,那么在懒汉式单例类被加载时不会将自己实例化。

代码语言:javascript
复制
package 单例模式;
/**
 * 懒汉式单例
 * @author xcbeyond
 * @date 2012-5-1 下午12:23:54
 */
public class LazySingleton {
  private static LazySingleton instance = null;
  
  //私有构造器
  private LazySingleton(){
  }
  
  //静态工厂方法,返回此类的唯一实例
  synchronized public static LazySingleton getInstance () {
    if(instance == null ) {
      instance = new LazySingleton();
    }
    return instance;
  }
}
代码语言:javascript
复制

3、登记式单例

为了克服饿汉式单例类和懒汉式单例类不可继承的缺点,于是引入了登记式单例类。

代码语言:javascript
复制
package 单例模式;

import java.util.HashMap;

/**
 * 登记式单例类:克服了饿汉式和懒汉式单例类的不可继承的缺点。
 * @author xcbeyond
 * @date 2012-5-1 下午12:35:23
 */
public class RegisterSingleton {
   private static HashMap reg = new HashMap();
  
  static {
    RegisterSingleton x = new RegisterSingleton();
    reg.put(x.getClass().getName(), x);
  }
  
  //保护的默认构造器
  protected RegisterSingleton () {
    
  }
  
  //静态工厂方法,返回此类唯一的实例
  public static RegisterSingleton getInstance(String name) {
    if(name == null) {
      name = "RegisterSingleton";
    }
    if(reg.get(name)==null) {
      try{
        reg.put(name, Class.forName(name).newInstance());
      }catch(Exception e) {
        System.out.println("Error happened");
      }
    }
    return (RegisterSingleton)reg.get(name);
  }
}

饿汉PK懒汉

饿汉式,类加载时进行了对象的实例化创建,即使多个进程并发操作,访问的实例也是唯一的,饿汉式线程安全。

懒汉式,第一次使用才会实例化,多个线程并发操作时,由于时间片的切换,可能导致线程风险。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿技术大咖 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档