侧边栏壁纸
  • 累计撰写 120 篇文章
  • 累计创建 281 个标签
  • 累计收到 11 条评论
标签搜索
隐藏侧边栏

单例模式的三种实现方式

骐骏
2017-03-27 / 0 评论 / 0 点赞 / 259 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-10-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1.饿汉模式

package com.fullstacker.study.designpattern.singleton;

/**

  • 饿汉模式 饿汉模式是线程安全的单例模式

  • @author xingguishuai

  • @create 2017-03-27-15:53
    **/
    public class HungrySingleton {

    private static HungrySingleton intance = new HungrySingleton();

    private HungrySingleton(){

    }

    public static HungrySingleton getIntance(){
    return intance;
    }
    }

2.懒汉模式

package com.fullstacker.study.designpattern.singleton;

/**

  • 懒汉模式

  • @author xingguishuai

  • @create 2017-03-27-15:58
    **/
    public class LazySingleton {
    private static LazySingleton intance ;

    private LazySingleton(){

    }
    /**

    • <p>功能描述:判断是否存在存在实例,如果不存在则,创建对象
    • 此时,否则返回实例,为线程不安全</p>
    • @return
    • @param
    • @author xingguishuai
    • @Date 2017-03-27 15:59
    • @since 1.0
      /
      public static LazySingleton getIntance(){
      if(null == intance){
      intance = new LazySingleton();
      }
      return intance;
      }
      /
      *
    • <p>功能描述:判断是否存在存在实例,如果不存在则,创建对象
    • 此时,否则返回实例,同步方式获取,但粒度较大,效率较低,可以使用双重判断的方法以优化</p>
    • @return
    • @param
    • @author xingguishuai
    • @Date 2017-03-27 15:59
    • @since 1.0
      */
      public static synchronized LazySingleton getIntanceSyn(){
      if(null == intance){
      intance = new LazySingleton();
      }
      return intance;
      }

}

3.双重判断的方法(懒汉模式优化)

package com.fullstacker.study.designpattern.singleton;

/**

  • 双重判断法

  • @author xingguishuai

  • @create 2017-03-27-16:06
    **/
    public class DubbleSingleton {
    private static DubbleSingleton intance ;

    private DubbleSingleton(){

    }
    /**

    • <p>功能描述:判断是否存在存在实例,如果不存在则,创建对象
    • 此时,否则返回实例,为线程不安全</p>
    • @return
    • @param
    • @author xingguishuai
    • @Date 2017-03-27 15:59
    • @since 1.0
      */
      public static DubbleSingleton getIntance(){
      //第一次检验是否为null
      if(null == intance){
      try {
      //模拟生成对象前准备
      Thread.sleep(2000);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      //同步代码块
      synchronized (DubbleSingleton.class){
      //创建对象前,再次校验是否为null
      if(null == intance){
      intance = new DubbleSingleton();
      }
      }
      }
      return intance;
      }

}

为什么要使用双重检测:

  1. 外部的check是为了提高效率,如果对象已经创建了,就可以直接返回避免锁竞争的消耗
  2. 内部的check是为了保证只创建一个实例, 因为要判断在这个线程持有锁之前的线程也有可能已经抢占锁成功,并且初始了完成,释放锁了

4.使用静态内部类来作为singleton的容器

public class StaticSingleton {
private StaticSingleton() {}
private static class SingletonHolder { //私有内部类在StaticSingleton 加载时,不初始化
    private static StaticSingleton instance = new StaticSingleton();
}

public static StaticSingleton getInstance () {
    return SingletonHolder.instance;
}

}

0

评论区