单例模式

定义
  • 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
优缺点
  • 优点

    • 在整个内存中只有一个实例,减少了内存开支。

    • 由于单例模式只生成一个实例, 所以可减少系统的性能开销

    • 可以避免对资源的多重占用

    • 可在系统设置全局的访问点,优化和共享资源访问

  • 缺点

    • 单例模式一般没有接口,扩展很困难,若要修改,除了修改代码基本没有第二种途径可以实现

    • 不利于单元测试

    • 单例类职责过重,在一定程度上,违背了单一职责

使用场景
  • 在整个项目中需要一个共享访问点或共享数据。

  • 创建一个对象时消耗的资源过多时,但又经常用到的对象

  • 频繁访问数据库或文件的对象

实现方式
  • 单例之懒汉式

    • 第一次调用才初始化,在效率上会有一点延迟,但可避免内存浪费

    • 非线程安全,用于多线程会出现问题

  • 单例之饿汉式

    • 在类加载时就初始化了,若实例没有使用时,将会造成内存浪费

    • 线程安全,可直接用于多线程而不出现问题

代码实现
  • 懒汉式之一般方式

       适用于单线程模式,延迟加载
    
    • Java版本

         public class LazySingleTon {
         
         private static  LazySingleTon  instance;
         
         private  LazySingleTon(){
             
         }
         public static LazySingleTon getInstance() {
             if(instance==null){
                 instance=new LazySingleTon()
             }
             return instance;
         }
      

      }

    • Kotlin版本

         class LazySingleTon  private constructor(){
         
             companion object {
              private  val  instance:LazySingleTon?=null
                 get(){
                     if(field==null){
                         field= LazySingleTon()
                     }
                     return  field
                 }
          
             }
      
         }
      
  • 懒汉式之双重校验方式

      使用synchronized添加同步锁,这样就可以使在初始化时在同一时间内只有一个线程可以对其访问,解决多线程同时访问的问题;但是也可能偶尔失效
    
    • Java版本

        public class LazySingleTon {
        
        
            private  static  LazySingleTon instace;
            private LazySingleTon() {
        
            }
            
            public static LazySingleTon newStance() {instace
                if(instace==null){
                  synchronized (LazySingleTon.class){
                       if(instace==null){
                           instace=new LazySingleTon();
                       }
                   }
                }
                return instace;
            }
        
            public void test() {
        
            }
        }
      
    • Kotlin版本

         class LazySingleTon {
         
             companion object {
                val  instance:LazySingleTon  by lazy(mode =LazyThreadSafetyMode.SYNCHRONIZED) {
                    LazySingleTon()
                }
             }
         
         }
      
  • 懒汉式之静态内部类

      使用静态内部类,只有当第一次调用newStance()时,虚拟机才会加载LazySingleTonHolder静态内部类,能够保证线程安全以及实例的唯一性 
    
    • Java版本

         public class LazySingleTon {
       
           private LazySingleTon() {
       
           }
       
           private static class LazySingleTonHolder {
               private static LazySingleTon INSTANCE = new LazySingleTon();
       
           }
       
           public static LazySingleTon newStance() {
               return LazySingleTonHolder.INSTANCE;
           }
       
           public void test() {
       
           }
       }
      
    • Kotlin版本

        class LazySingleTon {
        
            companion object {
               val  instance:LazySingleTon =LazySingletonHolder.holder
               }
            }
        
            private object  LazySingletonHolder{
                val holder:LazySingleTon=LazySingleTon()
            }
        
        }
      
  • 饿汉式

      类加载就会创建实例而不去管你用不用, 但是内存使用率低 线程安全。因为虚拟机保证了类只会加载一次,在装载类的时候是不会并发的
    
    • Java版本

         public class HungrySingleton {
         
             private static HungrySingleton INSTANCE = new HungrySingleton();
             private HungrySingleton() {
         
             }
             
             public static HungrySingleton newStance() {
                 return INSTANCE;
             }
         
             public void test() {
         
             }
         }
      
    • Kotlin版本

         	object  HungrySingleton {
         	    
         	    fun test() {
      
         	
         	    }
         	}
      
单例模式扩展之多例模式
  • 作用

      在设计时决定在内存中有多少个实例,方便系统进行扩展,修正单例可能存在的性能问题,提升系统的响应速度
    
  • 代码实现

    • 创建有上线的多例模式

        import android.util.Log;
        import java.util.Random;
        import java.util.Vector;
        
        public class MultipleObjectsSington {
            /**限制对象最多的个数*/
            private static  int  maxObjectNum=2;
            /**当前对象的索引值*/
            private static int  mCurrentObjectNum=0;
            /**用于存储多个对象*/
            private static Vector<MultipleObjectsSington> objects=new Vector<>();
        
            private static Vector<String> names=new Vector<>();
        
            static {
                objects.add(new MultipleObjectsSington("1"));
                objects.add(new MultipleObjectsSington("2"));
            }
            private MultipleObjectsSington(){
               this("");
            }
            private MultipleObjectsSington(String name ){
                 names.add(name);
            }
        
            /**
             * 获取对象实例
             * @return
             */
            public static MultipleObjectsSington getInstance(){
                Random random=new Random();
                mCurrentObjectNum=random.nextInt(maxObjectNum);
                return objects.get(mCurrentObjectNum);
            }
        
            /**
             * 对外暴露的方法
             */
            public void say(){
                Log.i("MultipleObjectsSington","这是第几个对象:"+names.get(mCurrentObjectNum));
            }
        }
      
    • 客户端调用

            for (i  in 0 until 5) {
                      val instance= MultipleObjectsSington.getInstance()
                      instance.say()
                  }
      
    • 结果

      	    这是第几个对象:1
      	    这是第几个对象:1
      	    这是第几个对象:2
      	    这是第几个对象:2
      	    这是第几个对象:2
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值