设计模式——单例模式

1. 什么是单例模式?

单例就是确保某一个类在软件应用的整个生命周期只有一个实例,而且能够自行实例化并向整个系统提供这个实例

2. 单例模式的特点?

1)单例类只能有一个实例(饿汉思想:保持饥饿,直到创建单一对象 懒汉思想:初始化应用时,就创建单一对象)
2)单例类必须自己创建自己的唯一实例(构造函数必须是private类型,不允许其他程序使用new对象)
3)单例类必须给所有其他对象提供这一实例(提供统一的接口供其他程序调用)

3. 单例模式有哪些用途?

节省资源,防止一个全局使用的类频繁的创建和销毁对象
比如说:
_1. Windows 是多进程多线程的,在操作同一个文件的时候,就不可避免的出现多个进程和多个线程同时操作一个文件的现象,所以必须通过一个唯一的实例来进行操作
2. 在线程池,缓存,日志对象,对话框,打印机等都要设计成单例

4. 单例模式的分类

  1. 懒汉模式
    只有首次获取成员变量时【getinstance()】才去初始化,如果单例对象一直没有使用,我们就不去初始化它,这样就可以节省系统的资源【不过这种开销往往不会太大】
  2. 饿汉模式
    在类加载的时候就实例化成员变量,避免线程的同步问题,在【getinstance()的时候去获取它,此时对象实例已经初始化】

5. JAVA单例模式

  1. 饿汉模式:
package com.example.jingbin.designpattern.singleton.ehan;

/**
 * Created by jingbin on 2016/10/27.
 * 1.单例模式的饿汉式[可用]
 * (1)私有化该类的构造函数
 * (2)通过new在本类中创建一个本类对象
 * (3)定义一个公有的方法,将在该类中所创建的对象返回
 * <p>
 * 优点:从它的实现中我们可以看到,这种方式的实现比较简单,在类加载的时候就完成了实例化,避免了线程的同步问题。
 * 缺点:由于在类加载的时候就实例化了,所以没有达到Lazy Loading(懒加载)的效果,也就是说可能我没有用到这个实例,但是它
 * 也会加载,会造成内存的浪费(但是这个浪费可以忽略,所以这种方式也是推荐使用的)。
 */

public class SingletonEHan {

    private SingletonEHan() {} //私有构造函数  防止程序在任何地方创建对象

    /**
     * 1.单例模式的饿汉式[可用]
     */
    private final static SingletonEHan singletonEHan = new SingletonEHan();

    public static SingletonEHan getInstance() {
        return singletonEHan;
    }



    /**
     * 2. 单例模式的饿汉式变换写法[可用]
     * 基本没区别
     */
    private static SingletonEHan singletonEHanTwo = null;

    static {
        singletonEHanTwo = new SingletonEHan();
    }

    public static SingletonEHan getSingletonEHan() {
        return singletonEHanTwo;
    }

}

2.懒汉模式:

package com.example.jingbin.designpattern.singleton.lanhan;

/**
 * Created by jingbin on 2016/10/28.
 * 3.单例模式的懒汉式
 */

public class SingletonLanHan {

    private SingletonLanHan() {
    }

    /**
     * 3.单例模式的懒汉式[线程不安全,不可用]
     */
    private static SingletonLanHan singletonLanHan;

    public static SingletonLanHan getInstance() {
        if (singletonLanHan == null) { // 这里线程是不安全的,可能得到两个不同的实例
            singletonLanHan = new SingletonLanHan();
        }
        return singletonLanHan;
    }

    /**
     * 4. 懒汉式线程安全的:[线程安全,效率低不推荐使用]
     * <p>
     * 缺点:效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。
     * 而其实这个方法只执行一次实例化代码就够了,
     * 后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。
     */
    private static SingletonLanHan singletonLanHanTwo;

    public static synchronized SingletonLanHan getSingletonLanHanTwo() {
        if (singletonLanHanTwo == null) { 
            singletonLanHanTwo = new SingletonLanHan();
        }
        return singletonLanHanTwo;
    }

    /**
     * 5. 单例模式懒汉式[线程不安全,不可用]
     * <p>
     * 虽然加了锁,但是等到第一个线程执行完instance=new Singleton()跳出这个锁时,
     * 另一个进入if语句的线程同样会实例化另外一个Singleton对象,线程不安全的原理跟3类似。
     */
    private static SingletonLanHan instanceThree = null;

    public static SingletonLanHan getSingletonLanHanThree() {
        if (instanceThree == null) {
            synchronized (SingletonLanHan.class) {// 线程不安全
                instanceThree = new SingletonLanHan();
            }
        }
        return instanceThree;
    }

    /**
     * 6.单例模式懒汉式双重校验锁[推荐用]
     * 懒汉式变种,属于懒汉式的最好写法,保证了:延迟加载和线程安全
     */
    private static SingletonLanHan singletonLanHanFour;

    public static SingletonLanHan getSingletonLanHanFour() {
        if (singletonLanHanFour == null) {
            synchronized (SingletonLanHan.class) {
                if (singletonLanHanFour == null) {
                    singletonLanHanFour = new SingletonLanHan();
                }
            }
        }
        return singletonLanHanFour;
    }
}

3.内部类

package com.example.jingbin.designpattern.singleton.inclass;

/**
 * Created by jingbin on 2016/10/28.
 * 7. 内部类[推荐用]
 * <p>
 * 这种方式跟饿汉式方式采用的机制类似,但又有不同。
 * 两者都是采用了类装载的机制来保证初始化实例时只有一个线程。
 * 不同的地方:
 * 在饿汉式方式是只要Singleton类被装载就会实例化,
 * 内部类是在需要实例化时,调用getInstance方法,才会装载SingletonHolder类
 * <p>
 * 优点:避免了线程不安全,延迟加载,效率高。
 */

public class SingletonIn {

    private SingletonIn() {
    }

    private static class SingletonInHodler {
        private static SingletonIn singletonIn = new SingletonIn();
    }

    public static SingletonIn getSingletonIn() {
        return SingletonInHodler.singletonIn;
    }
}

4 枚举
枚举的方法暂时不写

所以,综上所述,
要么使用饿汉模式:直接在类中的私有静态变量直接初始化;
要么使用懒汉模式:使用内部类,进行初始化,当需要使用时,进行懒加载

6. javascript单例模式

因为JS是单线程的,所以JS中不存在线程安全的问题,下面

var Singleton = (function(){
    var instantiated;
    function init(){
        return {
            publicMethod:function(){
                console.log('hello world');
            },
            publicProperty:'test'

        }
    }
    return {
        getInstance:function(){
            if(!instantiated){
                instantiated = init();
            }
            return instantiated;
        }
    }
})();

Singleton.getInstance().publicMethod();

参考博客:
http://blog.csdn.net/w2765006513/article/details/53743051
http://www.cnblogs.com/TomXu/archive/2012/02/20/2352817.html

更多设计模式整理文章:https://github.com/zhehuaxuan/DesignPattern

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值