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/
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    UIGestureRecognizer在多层视图中的触发问题
    mysql出现Waiting for table metadata lock的原因及解决方案
    SQL逆向工程
    自己总结的ruby on rails 查询方法
    hdu 1536 SG函数模板题
    spring 源码分析之BeanPostProcessor
    spring bean生命周期管理--转
    java.lang.Long cannot be cast to java.lang.Integer解决办法
    Mybatis之Oracle增删查改示例--转
    Anti-If: The missing patterns--转
  • 原文地址:https://www.cnblogs.com/Tony-Anne/p/6411884.html
Copyright © 2011-2022 走看看