单例模式Singleton

单例模式可以说是简单又复杂的一种设计模式!

单例就是对象只创建一个实例,并且提供一个全局的访问。但是说单例模式是复杂的设计模式也一点没错,因为涉及到DCL双锁检测(double checked locking)的讨论、涉及到多个

类加载器(ClassLoader)协同时、涉及到跨JVM(集群、远程EJB等)时、涉及到单例对象被销毁后重建等!那么这也就不是一个简单的设计模式了!首先,我创建一个简单的单例类吧!

package com.taobao.design;

import java.io.Serializable;

/**
 * 单例模式:创建型 
 */
public class SingletonA {
    private static SingletonA instance = null;
    
    public static SingletonA getInstance()
    {
        if(instance==null){                        //line1
            instance = new  SingletonA();        //line2
        }
        return instance;
    }
}
/**
 * 当多线程时,如果一个线程执行到line1时,另一个线程刚刚执行完line2,那么线程1就会再去new一个对象,
 * 所以上面这种情况就有可能new出两个对象那么哪个才是我们需要的对象呢?为了防止这种情况发生,那么我
 * 把getInstance方法改成同步的!
 */
class SingletonB {
    private static SingletonB instance = null;
    
    public synchronized static SingletonB getInstance()
    {
        if(instance==null){
            instance = new  SingletonB();
        }
        return instance;
    }
}
/**
 * 好!这下问题又来了!同步问题是解决了!什么问题呢!每次去调用getInstance方法时,都会有很大的性能
 * 问题,比如当两个线程现时执行到getInstance方法时,那其中某个线程肯定要等另一个线程执行完才能执行
 * ,所以至 少在至少耗时比例上存在很大性能问题的!接下来,把同步方法情改成同步代码块,在同步之前,
 * 做一下判断,双重锁定检查(DCL),这样应该解决了耗时问题了!但是总的说来一个单例这样是不上太复杂了
 */
class SingletonC{
    private static SingletonC instance = null;
    
    public static SingletonC getInstance()
    {
        if(instance==null){
            synchronized(SingletonC.class){
                if(instance==null){
                    instance = new  SingletonC();
                }
            }
        }
        return instance;
    }
}
/**
 * 返璞归真,一个类在一个ClassLoader中只会被初始化一次,那我在初始化时就把对象new出来不就可以了吗?
 * 哈哈 !原来这么简单!
 */
class SingletonD{
    private static SingletonD instance = new SingletonD();
    
    public static SingletonD getInstance(){
        return  instance;
    }
}
/**
 * 但是这样还存在一个问题,什么问题呢?上面这总是属于‘饿汉式’的创建方式,如果说要在创建之前做一些操作
 * ,比如读取配置文件,或者创建的时候必须传递某个参数给它,那该怎么办啊?ok,那我写个内部类用来创建对
 * 象,这样应该可以了吧!但是创建对象主要是通过1、new对象  2、反射构造单例对象  3、序列化构造单例,为了
 * 防止这样创建对象,那我还要加两个方法SingletonE()和readResolve(),ok,现在应该基本满足需求了吧!
 */
class SingletonE implements Serializable{
    
    private static class Singleton{
        static final SingletonE instance = new SingletonE();
    }
    
    private static SingletonE getInstance(){
        return Singleton.instance;
    }
    //防止new 
    private SingletonE(){}
    //防止通过反序列化得到对象
    private Object readResolve() {  
        return getInstance();  
    }
    
}

总结:具体该如果创建单例,当然还是看情况而定,没有哪种创建方法是万能的!

原文地址:https://www.cnblogs.com/hnhcc39/p/2586453.html