7、单例模式

本文深入探讨了单例模式的三种实现方式:静态变量即时加载、延迟加载,静态内部类即时加载,以及多线程下的延迟创建与加锁。通过代码示例详细解析了每种方式的优缺点。

1、单例模式介绍

单例模式是为了在系统使用过程中,同一个对象之创建一次,后续不断的重复使用,实现方式:1、静态变量(即时加载、延迟加载);2、静态内部类即时加载

2、单例模式几种实现方式

  • 1、单线程/多线程操作(类加载创建)

      /**
       * [@Author](https://my.oschina.net/arthor) liufu
       * @CreateTime 2017/8/15  15:08
       */
      public class SingleThreadObject {
    
          //类装载就构建了本对象,通过静态属性永久指向这个对象地址,从而达到单例效果
          private static SingleThreadObject instance = new SingleThreadObject();
    
          public static SingleThreadObject getInstance(){
              return instance;
          }
    
          //假设在另一个类中使用它(为了方便,写在了同一个类)
          public static void main(String[] args) {
              SingleThreadObject obj1 = SingleThreadObject.getInstance();
              SingleThreadObject obj2 = SingleThreadObject.getInstance();
    
              System.out.println(obj1 == obj2);
              System.out.println(obj1.hashCode() == obj2.hashCode());
          }
      }
    

    效果截图

  • 2、单线程/多线程操作(延迟创建,加锁)

    由于需要传递参数,对象久不能够在类加载的时候构建,而是需要在线程用到的时候,传递参数进来,比如

      /**
       * [@Author](https://my.oschina.net/arthor) liufu
       * @CreateTime 2017/8/15  15:08
       */
      public class SameThreadObject {
          private Properties param;
    
      //这个构造方法最好设置为private,这样外面无法new,只能够通过getInstance来创建
          private SameThreadObject(Properties param){
              this.param = param;
          }
    
          //类装载就构建了本对象,通过静态属性永久指向这个对象地址,从而达到单例效果
          //由于需要传递参数,只能延迟创建,而且多线程加锁,只能够由一个线程来构建
          private static SameThreadObject instance;
    
          //多线程,加锁,双重判断
          public static SameThreadObject getInstance(Properties param){
              if (instance == null){
                  synchronized ("getInstance"){
                      if (instance == null){
                          instance = new SameThreadObject(param);
                      }
                  }
              }
              return instance;
          }
    
          //假设在另一个类中使用它(为了方便,写在了同一个类)
          public static void main(String[] args) {
              Properties param = new Properties();
              SameThreadObject obj1 = SameThreadObject.getInstance(param);
              SameThreadObject obj2 = SameThreadObject.getInstance(param);
    
              System.out.println(obj1 == obj2);
              System.out.println(obj1.hashCode() == obj2.hashCode());
          }
      }
    

  • 3、单线程/多线程操作(内部静态类)

    静态内部类延迟创建,类加载器天生对多线程友好,兼顾延迟加载和多线程问题

    问题是:没法传递参数,因为一旦调用这个类,他就创建了这个对象

      import java.util.Properties;
      /**
       * [@Author](https://my.oschina.net/arthor) liufu
       * @CreateTime 2017/8/15  15:08
       */
      public class DelyCreateInnerObject {
    
          //假设在另一个类中使用它(为了方便,写在了同一个类)
          public static void main(String[] args) {
              Properties param = new Properties();
              DelyCreateInnerObject obj1 = DelyCreateInnerObject.getInstance();
              DelyCreateInnerObject obj2 = DelyCreateInnerObject.getInstance();
    
              System.out.println(obj1 == obj2);
              System.out.println(obj1.hashCode() == obj2.hashCode());
          }
    
          /**
           * 即实现了延迟创建,也实现了多线程下锁带来的性能消耗
           * 这两个是绝佳组合
           * @return
           */
          private static DelyCreateInnerObject getInstance(){
              return  DelyCreateInnerObjectNest.instance;
          }
    
          static class DelyCreateInnerObjectNest{
              private static DelyCreateInnerObject instance = new DelyCreateInnerObject();
          }
      }
    

转载于:https://my.oschina.net/liufukin/blog/2222539

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值