设计模式 -- 单例模式

设计模式  -- 单例模式

 

什么是单例模式? 

       单例模式是一种对象创建模式, 使用单例模式,可以保证为一个类只生产一个实例对象,也就是说,整个程序空间,只有该类的一个实例对象。

 

为什么需要使用单例模式?

    在应用系统开发中,我们常常有以下需求:
        - 在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象
        - 在整个程序空间使用全局变量,共享资源
        - 大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。

 

单例模式的简单实现

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

单例模式的三种实现?

   饿汉式。

     饿汉是典型的空间换时间

public class Person {
    public static final Person person = new Person();
    private String name;
    
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    //构造函数私有化
    private Person() {
    }
    
    //提供一个全局的静态方法
    public static Person getPerson() {
        return person;
    }
}

 

但是这个例子有什么问题呢,上面的例子并不能保证对象不被创建出来,完全可以使用 new Person(0 方法创建对象,为了避免创建对象,怎么办,声明一个 private 的构造函数

 懒汉式。

 懒汉式是典型的时间换空间,每次获取实例都会判断要不要新建实例,浪费时间

由于懒汉式没有加同步,线程上是不安全的。

public class Person2 {
    private String name;
    private static Person2 person;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    //构造函数私有化
    private Person2() {
    }
    
    //提供一个全局的静态方法
    public static Person2 getPerson() {
        if(person == null) {
            person = new Person2();
        }
        return person;
    }
}

 

上面的实现是否有问题呢? 我们考虑一个并发的场景,多个线程在判断 person= null 时,就会出现多个 Person实例,并发场景也不能保证单例。怎么办呢,采用同步阻塞,或者 “双检锁”。

在并发的模式下可能失效,需要加锁

/**
 * 版权所有 (c) 2018,xiaom有限公司  
 */
package designPattern.singleton;

/**
 * 类说明
 * 
 * <pre>
 * Modify Information:
 * Author        Date          Description
 * ============ =========== ============================
 * DELL          2018年1月3日    Create this file
 * </pre>
 * 
 */

public class Person3 {
    private String name;
    private static Person3 person;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    //构造函数私有化
    private Person3() {
    }
    
    //提供一个全局的静态方法,使用同步方法
    public static synchronized Person3 getPerson() {
        if(person == null) {
            person = new Person3();
        }
        return person;
    }
}


     3.双重检查。 减小了锁的粒度,不再是在方法上加锁。

/**
 * 版权所有 (c) 2018,xiaom有限公司  
 */
package designPattern.singleton;


/**
 * 类说明
 * 
 * <pre>
 * Modify Information:
 * Author        Date          Description
 * ============ =========== ============================
 * DELL          2018年1月3日    Create this file
 * </pre>
 * 
 */


public class Person4 {
    private String name;


    private static volatile Person4 person;


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    // 构造函数私有化
    private Person4() {
    }


    // 提供一个全局的静态方法
    public static Person4 getPerson() {
        if (person == null) {
            synchronized (Person4.class) {
                if (person == null) {
                    person = new Person4();
                }
            }
        }
        return person;
    }
}







了解更多,关注【程序员开发者社区】

 

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie
应支付0元
点击重新获取
扫码支付

支付成功即可阅读