欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

单例模式(创建型)

程序员文章站 2022-07-13 23:44:28
...

特点:一个类只能有一个实例对象。
单例实现要求:

  1. 静态单例实例对象
  2. 私有构造方法
  3. public 静态函数用以返回实例对象
1. 懒汉式单例
---线程不安全单例
public class Singleton
{
    private static Singleton singleton;
    private Singleton(){}

    public static Singleton getSingleton()
    {
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

---线程安全单例
public class Singleton
{
    private static Singleton singleton;
    private Singleton(){}

    public static synchronized Singleton getSingleton()
    {
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}
2. 饿汉式单例(线程安全)
public class Singleton
{
    private static Singleton singleton = new Singleton();
    private Singleton(){}

    public static Singleton getSingleton()
    {
        return singleton;
    }
}
3. 双重校验锁(线程安全)
public class Singleton
{
    private static volatile Singleton singleton;
    private Singleton(){}

    public static Singleton getSingleton()
    {
        if(singleton == null){
            synchronized (Singleton.class){
                if(singleton == null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

volatile关键字的作用是防止JVM在进行new Singleton()操作时进行指令重排从而导致多线程操作中获取到未初始化完全的Singleton对象实例。

4. 静态内部类(线程安全)
public class Singleton
{
    private static class SingletonHolder{
        private static final Singleton singleton = new Singleton();
    }

    private Singleton(){}

    public static Singleton getSingleton()
    {
        return SingletonHolder.singleton;
    }
}

5. 枚举(线程安全)
public enum Singleton
{
    singleton;
    public Singleton getSingleton(){
        return singleton;
    }
}
破坏单例的情况:

反射调用构造函数
序列化单例对象

解决方法

使用枚举方式建立单例模型

序列化:在单例类中添加readResolve()方法

public class Singleton implements Serializable
{
    ......
    private Object readResolve(){
        return singleton;
    }
}

反射:重写构造函数,在第二次创建单例时抛出异常

public class Singleton implements Serializable
{
    private static Singleton singleton;
    private static boolean flag = false;
    private Singleton(){
        synchronized (Singleton.class){
            if(flag == false){
                flag = !flag;
            }else{
                throw new RuntimeException("单例模式已被创建");
            }
        }
    }
    public static Singleton getSingleton()
    {
        .......
    }
}