• 单例模式


    对今天学习的Singleton Pattern简单总结下:

    定义:保证一个类只有一个实例,必须自己创建自己的实例,并提供一个访问它的全局访问点。

    • private 构造函数;
    • private static 成员变量:缓存实例;
    • public static 方法:创建类实例;

    作用

    • 保证唯一实例,减少内存开支,避免对资源的多重占用;
    • 提供对唯一实例的受控访问;
    • 全局变量必须在程序一开始就创建好,单例模式可以延迟初始化;

    适用场合   

    • 控制资源的使用,通过线程同步来控制资源的并发访问;   
    • 控制实例产生的数量,达到节约资源的目的; 
    • 作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信;

    普通单例模式

    通常情况下,单例模式分为饿汉式和懒汉式,具体代码参见下方

    • 饿汉式:预先创建实例、占用内存,但线程安全
    • 懒汉式:使用时再创建实例、相对节省内存,但存在线程安全问题 

    多线程下的单例模式

    进程加锁 (懒汉式 -> 饿汉式) –> 双重锁定(Double-Check Locking) –> 静态内部类 –> 枚举 

    懒汉式

     public class Singleton{   // 单例-懒汉式
         private static Singleton instance;
         private Singleton() {}
         public static synchronized Singleton getInstace()
         {
             if(null==instance)
                 instance = new Singleton();
             return instance;
         }
     }

    :同步方法解决多线程问题。仅第一次设置instance需要同步,之后每次调用此方法,同步都是累赘降低性能。

    双重锁定 - 懒汉式改进版

     public class Singleton{ // 单例-双重锁定(懒汉式改进版)
         private volatile static Singleton instance;
         private Singleton() {}
         public static Singleton getInstace()
         {
             if(null==instance){
                 synchronized(Singleton.class){
                     if(null==instance)
                         instance = new Singleton();
                 }
             }
             return instance;
         }
     }

    :确保实例仅在未创建时加锁,亦能保证多线程安全。
    volatile:避免内存模型允许的’无序写入’(某个线程可能会获得一个未完全初始化的实例[构造完整但是部分初始化])导致失败。

    饿汉式

     public class Singleton{   // 单例-饿汉式 
       private static Singleton instance = new Singleton();
       private Singleton() {}
       public static Singleton getInstace()
       {
         return instance;
       }
     }  

    :使用静态初始化(无需显示编写线程安全代码),加载时即实例化,提前占用系统资源。

    静态内部类

     public class Singleton{  // 静态内部类
         private Singleton() {}
         private static class SingletonHelper{
             private final static Singleton instance = new Singleton();
         }
         public static Singleton getInstace(){
             return SingletonHelper.instance;
         }
     }

    :加载时不会初始化静态变量instance,达到延时加载。
      static:成员变量只保存一份副本;
      final:保证变量不可变。

    枚举

    public class Singleton{  // 枚举
         private Singleton() {}
         
     }  

    :单元素的枚举类型是实现Singleton的最佳方式。

    参考

    ---  纵使山重水复,亦会柳暗花明   sunqh1991@163.com   欢迎关注,互相交流
  • 相关阅读:
    Android菜鸟的成长笔记(5)——Android系统源代码你下载了吗?
    2014年你不用担心的10件事
    Android菜鸟的成长笔记(4)——你真的理解了吗?
    3. MariaDB设置主从复制
    2. MariaDB激活二进制日志
    如何在CSDN博客自定义栏目中添加“给我写信”
    告别码农,成为真正的程序员
    微信公众平台开发(75)自定义菜单
    大文件分片上传,断点续传,秒传 实现
    大文件上传-大视频上传,T级别的,求解决方案
  • 原文地址:https://www.cnblogs.com/wjcx-sqh/p/5929916.html
Copyright © 2020-2023  润新知