Java 设计模式——单例模式详解

  • 前言

    一直在学习Android, 但是都总觉得是在造轮子, 所以还是得把java学深刻, 不然很多线程不安全的东西就会出现.


  • 单例模式

    1. 饿汉式单例式

      所谓饿汉就是在程序启动单例模式类被加载的时候, 单例模式实例就已经被创建

      public class Singleton{
          private static Singleton singleton = new Singleton();
          private Singleton(){}
          public static Singleton getInstance(){
              return singleton;
          }
      }

      缺点: 不管是否需要都会创建这个对象实例, 但是我们总希望能够按需求做事.

    2. 懒汉式(线程不安全)

      懒汉: 当程序第一次访问单例模式实例时才进行创建.

      public class Singleton{
          private static Singleton singleton;
          private Singleton(){}
          public static Singleton getInstance(){
              if(singleton==null){
                  singleton = new Singleton();
              }
              return singleton;
          }
      }

      缺点: 在多线程中不能正常工作,详情请点击: 解决单例设计模式中懒汉式线程安全问题

    3. 懒汉(线程安全)

      很明显下面代码中加了一个关键字 synchronized 锁

      public class Singleton{
          private static Singleton singleton;
          private Singleton(){}
          public static synchronized Singleton getInstance(){
              if(singleton==null){
                  singleton = new Singleton();
              }
              return singleton;
          }
      }

      缺点: 虽然能在多线程正常工作, 效率太低.

    4. 静态内部类

      当Singleton类被加载的时候, singleton并没有被初始化, 因为SingletonHolder类没有被主动使用,只有调用getInstance方法时才会显示加载SingletonHolder类

      public class Singleton{
          private static class SingletonHolder{
              private static Singleton singleton = new Singleton();
          }
          private Singleton(){}
          public static Singleton getInstance(){
              return SingletonHolder.singleton;
          }
      }

      注: 以上的实现方法都有两个共同缺点;都需要额外的工作来实现序列化; 可以使用反射强行调用私有构造器(可以让构造器在创建第二的实例时抛异常).

    5. 枚举

      这种写法很特殊, 在实际工作中也很少见, 在Android平台是不被推荐的.
      但是线程安全和防止反射强行调用构造器, 还提供了自动序列化机制.

      public enum Singleton{
          INSTANCE;
          public void whateverMethod(){
          }
      }
    6. 双重检验锁

      在jdk1.5之后就有了双重校验锁, 这是我觉得最好的一个方法.

      public class Singleton{
          private static Singleton singleton;
          private Singleton(){}
          public static Singleton getInstance(){
              if(singleton==null){
                  synchronized(Singleton.class){
                      if(singleton==null){
                          singleton = new Singleton();
                      }
                  }
              }
              return singleton;
          }
      }
  • 牢记

    不管采用什么方式实现, 都要牢记单例的三大要点:

    • 线程安全
    • 延迟加载
    • 序列化与反序列化安全
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值