zoukankan      html  css  js  c++  java
  • 01、单例模式

    单例模式(Singleton Pattern)

    定义:确保某个类只有一个实例,并且自行实例化并向整个体系提供这个实例

    需求:保证对象只创建一次

    场景:线程池、缓存、日志对象、对话框等常被设计为单例。

    Singleton 通过构造方法限定 private 避免类在外部被实例化,在同一个虚拟机范围内,Singleton 的实例只能通过 getInstance 访问。

    事实上,通过 Java 的反射机制能够实例化构造函数为 private 的类,基本是上所有的单例都失效。

     

      优点:减少了内存的消耗,重用。

    单例通用代码01:(饿汉式)

    public class Singleton {
    
        private static final Singleton singleton = new Singleton();
    
        private Singleton(){
        }
    
        public static Singleton getInstance(){
            return singleton;
        }
       public void say(){} }

    可能产生多个实例02:(懒汉式)

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

     在高并发的情况下,可能在 instance ==null 与 new Singleton 之间产生多例。

    解决多例的问题:03(懒汉式)方法上加锁

    public class Singleton {
        private static  Singleton instance = null;
    
        private Singleton(){}
    
        public static synchronized   Singleton getInstance(){
            if(instance==null){
                instance = new Singleton();
            }
            return  instance;
        }
    
        public void say(){
            //todo something
        }
    }

    使用双检查锁:04(懒汉式)双检查,方法内加锁

    public class Singleton {
        private static  Singleton instance = null;
    
        private Singleton(){}
    
        public  static  Singleton getInstance(){
            if(instance==null){
                synchronized (Singleton.class) {
                    if(instance==null) {
                        instance = new Singleton();
                    }
                }
            }
            return  instance;
        }
    
        public void say(){
            //todo something
        }
    }

    饿汉式的单例模式,不会出现线程安全的问题。

    懒汉式本身是非线程安全的。

    方法上加锁与方法内双检查加锁:方法上加锁,虽然线程安全,但是每次都要同步,会影响性能 99% 的情况下是不需要同步的。

    方法内检查2次加锁,确保第一次调用的时候加锁,这样是线程安全的,避免了性能的损耗。

    扩展:固定数量的单例

    public class ExtSingleton {
    
        //最大单例个数
        private static int maxNumOfSingleton = 2;
    
        //单例名称
        private static ArrayList<String> nameList = new ArrayList<>();
    
        //单例集合
        private static ArrayList<ExtSingleton> singletons = new ArrayList<>();
    
        private ExtSingleton(){}
    
        private ExtSingleton(String name){
            nameList.add(name);
        }
    
        static {
            for(int i=0;i<maxNumOfSingleton;i++){
                singletons.add(new ExtSingleton("singleton:"+i));
            }
        }
    
        public static ExtSingleton getInstance(){
            //todo 获取单例某个对象
            return singletons.get(0);
        }
    
    }
  • 相关阅读:
    VINS_Fusion 框架
    VINS_Fusion 前端源码解析
    堆与优先队列
    LSD-SLAM简介
    直接法和特征点法的区别与优缺点
    CV::Mat介绍
    C++ 位运算
    OPENCV重要函数
    C++ 优先队列
    特征点法的巅峰之作—ORBSLAM2
  • 原文地址:https://www.cnblogs.com/baizhuang/p/10401120.html
Copyright © 2011-2022 走看看