单例模式

翻译自:http://blog.csdn.net/dmk877/article/details/50311791

/**
 * Created by admin on 2016/8/24.
 */
public class Singleton {

    //饿汉模式
    /**
     * 1 类加载时初始化 内存浪费但可忽略,可以使用
     */

    /*private static Singleton instance = new Singleton();
    private Singleton(){};

    public static Singleton getInstance(){
        return instance;
    }*/
    /**
     * 2 饿汉式变换写法[可用]
     */
    /*private static Singleton instance = null;
    static{
        instance = new Singleton();
    }
    private Singleton(){};

    public Singleton getInstance(){
        return instance;
    }*/

    //懒汉模式
    /**
     * 1 线程不安全,不可用
     * 这种方式是在调用getInstance方法的时候才创建对象的,所以它比较懒因此被称为懒汉式。
     * 在上述两种写法中懒汉式其实是存在线程安全问题的,喜欢刨根问题的同学可能会问,存在怎
     * 样的线程安全问题?怎样导致这种问题的?好,我们来说一下什么情况下这种写法会有问题。
     * 在运行过程中可能存在这么一种情况:有多个线程去调用getInstance方法来获取Singleton
     * 的实例,那么就有可能发生这样一种情况当第一个线程在执行if(instance==null)这个语句
     * 时,此时instance是为null的进入语句。在还没有执行instance=new Singleton()时(
     * 此时instance是为null的)第二个线程也进入if(instance==null)这个语句,因为之前进
     * 入这个语句的线程中还没有执行instance=new Singleton(),所以它会执行instance=
     * new Singleton()来实例化Singleton对象,因为第二个线程也进入了if语句所以它也会实
     * 例化Singleton对象。这样就导致了实例化了两个Singleton对象。所以单例模式的懒汉式是
     * 存在线程安全问题的
     */
    /*private static Singleton instance = null;
    private Singleton(){};

    public static Singleton getInstance(){
        if(null==instance){
            instance = new Singleton();
        }
        return instance;
    }*/
    /**
     * 2
     * 同上,线程不安全,当一个线程还没有实例化Singleton时另一个线程执行到if(instance==null)
     * 这个判断语句时就会进入if语句,虽然加了锁,但是等到第一个线程执行完instance=
     * new Singleton()跳出这个锁时,另一个进入if语句的线程同样会实例化另外一个Singleton对象,
     * 线程不安全的原理同上。
     */
    /*private static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if(null==instance){
            synchronized(Singleton.class){
                instance = new Singleton();
            }
        }
        return instance;
    }*/
    /**
     * 3 线程安全,效率低,不推荐使用
     * 效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。
     * 而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了
     */
    /*private static Singleton instance;
    private Singleton(){};

    public static synchronized Singleton getInstance(){
        if(null==instance){
            instance = new Singleton();
        }
        return instance;
    }*/
    /**
     * 4 双重校验锁[推荐用]
     * Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次
     * if (instance== null)检查,这样就可以保    证线程安全了。这样,实例化代码
     * 只用执行一次,后面再次访问时,判断if (instance== null),直接return实例化
     * 对象。
     * 优点:线程安全;延迟加载;效率较高。
     */
    /*private static Singleton instance = null;
    private Singleton(){}

    public static Singleton getInstance(){
        if(null==instance){
            synchronized (Singleton.class){
                if(null==instance){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }*/

    //内部类 可以使用
    /**
     * 这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制
     * 来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类
     * 被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类
     * 被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会
     * 装载SingletonHolder类,从而完成Singleton的实例化。类的静态属性只会在
     * 第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类
     * 进行初始化时,别的线程是无法进入的。
     * 优点:线程安全,延迟加载,效率高。
     */
    /*private Singleton(){}
    private static class  SingletonHolder{
        private static Singleton instance = new Singleton();
    }

    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }*/

    //枚举见SingletonEnums, 极简单,JDK1.5推荐使用
    /**
     * 可以看到枚举的书写非常简单,访问也很简单在这里SingletonEnum.instance这里
     * 的instance即为SingletonEnum类型的引用所以得到它就可以调用枚举中的方法了。
     * 借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止
     * 反序列化重新创建新的对象。可能是因为枚举在JDK1.5中才添加,所以在实际项目开发
     * 中,很少见人这么写过,这种方式也是最好的一种方式,如果在开发中JDK满足要求的情
     * 况下建议使用这种方式
     */
    SingletonEnum e = SingletonEnum.instance;
}

SingletonEnum

/**
 * Created by admin on 2016/8/24.
 */
public enum SingletonEnum {
    instance;
    private SingletonEnum(){}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值