设计模式之单例模式

 设计模式有很多种,单例模式只是其中一种,很多面试官都会考,但是怎么写出高水平的单例模式呢?今天给大家分享下。

      首先单例模式保证类的对象在内存中全局唯一性,主要是为了减少对象对资源的占用。

       那么要怎么实现呢?问题有2个,一是类的外部不允许直接构建此类对象,二是类的外部只能通过静态方法访问此对象。解决方法:首先是构造方法私有化,在类的内部构建对象,通过定义一个静态方法,通过这个方法直接返回此对象。

class Singleton01{
  private Singleton01(){}
  private static Singleton01 instance;
  public static Singleton01 getInstance(){
    if(instance==null){
      instance=new Singleton01();
    }
    return instance;
  }
}
但是这个方法存在线程安全问题,如果多个线程同时访问getInstance()方法,
可能会创建多个对象,那么该怎么办呢?
可以使用synchronized关键字,保证在某个时间只有一个线程能访问getInstance()
方法。
class Singleton02{
  private Singleton02(){}
  private static Singleton02 instance;
  public static synchronized Singleton02 getInstance(){
    if(instance==null){
      instance=new Singleton02();
    }
    return instance;
  }
}
这个虽然解决了线程安全问题,但是如果多个线程访问getInstance()方法,
只有一个线程执行,其他线程全部阻塞,会极大的影响性能。
熟悉synchronized的小伙伴都知道,synchronized方法不仅可用于修饰方法,
还可作用于静态方法和代码块。

class Singleton03{
  private Singleton03(){}
  private static volatile Singleton03 instance;
  public static Singleton03 getInstance(){
    if(instance==null){
      synchronized(Singleton03.class){
        if(instance==null){
          instance=new Singleton03();
        }
      }
    }
    return instance;
  }
}
这一行代码 instance=new Singleton03();其实是3个步骤,
首先为instance分配内存空间,然后初始化instance,最后将instance指向分配的
内存空间,但是在jvm中会为了提高效率进行指令重排序。因此可能会得到一个没有
实例化的instance对象,使用volatile声明对象,防止指令重排序。
但是不适合频繁访问。
class Singleton04{
  private Singleton04(){}
  //类加载时创建对象
  private static final Singleton04 instance=new Singleton04();
  //没有阻塞问题适合频繁访问
  public static Singleton04 getInstance(){
    return instance;
  }
}
这个单例设计适合频繁访问,如果对象比较大,在类加载的时候就创建了此对象,
但是假如不适用,就可能长时间占用。我们可以使用延迟加载策略。
class Singleton05{
  private Singleton05(){}
  static class Lazy{//只有使用这个内部类,才会被加载
    //使用外部类的成员方法,成员变量时,只加载外部类,这个内部类不被加载
    public static final Singleton05 instance=new Singleton05();
    
  }
  public static Singleton05 getInstance(){
    //何时需要何时加载
    return Lazy.instance;
  }
}

单例模式你学会了吗?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值