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

    单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    通常我们可以定义一个全局变量使得一个对象被访问,但它不能阻止我们实例化多个对象,所以一个最好的办法就是让类自身保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且提供一个访问该实例的方法。

    public class Singleton {
        private static Singleton instance;
        private Singleton(){
            
        }
        public static Singleton getInstance(){
            if(instance == null){
                instance = new Singleton();
            }
            return instance;
        }
    }
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Singleton s1 = Singleton.getInstance();
            Singleton s2 = Singleton.getInstance();
            if(s1 == s2){
                System.out.println("两个对象是相同的实例");
            }
        }
    
    }

    这里特别要注意singleton类的构造方法是私有的,这样可以防止通过new的方式创建该对象,而只能通过getInstance方法获得。我们还有些细节需注意,在多线程程序中,如果多个线程同时访问singleton类,并调用getInstance方法,会有可能创建多个对象。这时可以给进程一把锁来处理。

    public class Singleton1 {
        private static Singleton1 instance;
        private static final Object syncRoot = new Object();
        private Singleton1(){
            
        }
        public static Singleton1 getInstance(){
            synchronized (syncRoot) {
                if(instance == null){
                    instance = new Singleton1();
                }
            }
            return instance;
        }
    }

    这段代码使得对象由最先进入的那个线程创建,以后线程在进入时不会再去创建对象实例。由于有了lock,保证了在多线程情况下不会创建多个对象。但这个写法在每次调用getInstance方法时都要获取锁,影响程序性能,所以这个类还得改良。

    public class Singleton2 {
        private static Singleton2 instance;
        private static final Object syncRoot = new Object();
        private Singleton2(){
            
        }
        public static Singleton2 getInstance(){
            //先判断实例是否存在,不存在再加锁处理,此做法被称为Double-Check Locking(双重锁定)
            if(instance == null){
                synchronized (syncRoot) {
                    if(instance == null){
                        instance = new Singleton2();
                    }
                }
            }
            return instance;
        }
    }

    实例在未被创建时再加锁处理,保证了多线程的安全,这种做法被称为Double-Checking Locking 双重锁定。

    除了上面几种懒汉式单例类,还有一种饿汉式单例,这种静态初始化方式是在自己被加载时就将自己实例化。所以会提前占用系统资源。

    饿汉式单例类:

    public class Singleton3 {
        private static final Singleton3 instance = new Singleton3();
        private Singleton3(){
            
        }
        public Singleton3(String name){
            
        }
        public static Singleton3 getInstance(){
            return instance;
        }
    }

    需要注意的是instance的修饰为static final。

  • 相关阅读:
    BZOJ3752 : Hack
    XIV Open Cup named after E.V. Pankratiev. GP of SPb
    XIII Open Cup named after E.V. Pankratiev. GP of Ukraine
    BZOJ2087 : [Poi2010]Sheep
    BZOJ2080 : [Poi2010]Railway
    BZOJ2082 : [Poi2010]Divine divisor
    Moscow Pre-Finals Workshop 2016. National Taiwan U Selection
    XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
    XIII Open Cup named after E.V. Pankratiev. GP of Azov Sea
    XIII Open Cup named after E.V. Pankratiev. GP of SPb
  • 原文地址:https://www.cnblogs.com/shicaiyou/p/9356027.html
Copyright © 2011-2022 走看看