zoukankan      html  css  js  c++  java
  • 设计模式:单例模式

      单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例,并提供一个全局访问点

      使用单例模式的目的在于尽可能节约内存空间,减少GC的消耗。

      一个类能否成为单例,主要就是说这些类在应用中如果有两个以上实例会引起一定错误。

      首先看下一个最原始的单例模式

    public class Singleton {
    
        //一个静态的实例
        private static Singleton singleton;
    
        //私有化构造函数
        private Singleton(){}
    
        //给出一个公共的静态方法返回一个单一实例
        public static Singleton getInstance(){
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }
    }

      上面最原始的代码主要通过静态实例+私有化构造方法来创建的。但是如果考虑到多线程的话,上面的代码就不行了,那么有人想到用synchronize,

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

    做法是很简单,但是会造成很多无谓的等待,是非常不好的设计。其实,将上面的更改下就会好多了,如下:

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

    在只有实例为null的情况下才会去创建同步,大大减少了同步时间,而在同步内的if判断是因为,如果线程A和线程B都在synchronized外判断了singleton为null,然后A获取了线程锁然后将singleton实例化了,最后释放锁,这时,B拿到了锁,而如果没有在此判断singleton是否为nul的话,B就会在创建一个实例了。

    虽然上面的已经基本解决了在多线程下的单例模式,但考虑其他方面,上述方式也存在一定局限。下面介绍最终两种方式:饿汉模式和懒汉模式

      饿汉模式:系统中对象只有有一个唯一的实例,将对象的创建交给成员变量,空间换时间,一开始就创建实例。但容易造成资源的浪费,不过也没什么影响。

    public class MyServlet {
        private static MyServlet instance = new MyServlet();
        private MyServlet(){}
        public static MyServlet getInstance(){
            return instance;
        }
    }

      懒汉模式(推荐):用到实例时候再初始化对象,使用静态内部类实现可以避免多线程下的安全问题。

    public class LazySingleton {
        private static class Inner{
            private static LazySingleton instance = new LazySingleton();
        }
        private LazySingleton(){}
        public static LazySingleton getInstance(){
            return Inner.instance;
        }
    }

       下一节:命令模式

    作者:哀&RT
    出处:博客园哀&RT的技术博客--http://www.cnblogs.com/Tony-Anne/
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Java学习二十九天
    Java学习二十八天
    47. Permutations II 全排列可重复版本
    46. Permutations 全排列,无重复
    subset ii 子集 有重复元素
    339. Nested List Weight Sum 339.嵌套列表权重总和
    251. Flatten 2D Vector 平铺二维矩阵
    217. Contains Duplicate数组重复元素
    209. Minimum Size Subarray Sum 结果大于等于目标的最小长度数组
    438. Find All Anagrams in a String 查找字符串中的所有Anagrams
  • 原文地址:https://www.cnblogs.com/Tony-Anne/p/6411884.html
Copyright © 2011-2022 走看看