单例模式

目录

单例的实现

1.饿汉式

2.懒汉式

3.双重检测机制

4.静态内部类

5.枚举


单例的实现

  • 构造函数的访问权限为private,避免外部通过new创建实例
  • 对象创建时的线程安全问题
  • 是否支持延时加载(懒汉式、饿汉式)
  • 性能(是否加锁)

单例模式的核心:一个类只允许创建一个对象。

1.饿汉式

在类加载的时候就创建对象并初始化

public class Singleton{

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

2.懒汉式

相对于饿汉式,支持延迟加载

public class Singleton{

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

以上代码在单线程下运行是没有问题的,但是在多线程下,就会出现实例化多个类对象的情况。

原因是当线程A进入到if判断条件之后,开始实例化对象,此时,instance依然为null;又有线程B进入到if判断条件中,之后也会通过该判断,进入到方法里面创建一个实例对象。所以我们应该对该方法加锁,保证多线程情况下只创建一个实例。但是加锁会降低系统的性能。

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

}

3.双重检测机制

在Java中,使用volatile关键字防止指令重排。

public class Singleton(){
    private volatile static Singleton instance;
    public List<String> list;
    private Singleton (){
        list = new ArrayList<String>();
    }
    public static Singleton getInstance(){
        if(instance == null){
            synchronized (Singleton.class){
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }    

}

4.静态内部类

public class Singleton{

    public List<String> list;
    private Singleton(){
        list = new ArrayList<String>();
    };
    public static class InnerSingleton(){
        private static Singleton instance = new Singleton();
    }
    public static Singleton getInstance(){
        return InnerSingleton.instance;
    }
   
}

5.枚举

public class EnumMode {
    private static EnumMode instance;

    private EnumMode(){}

    private static EnumMode getInstance(){
        return Singleton.SINGLETON.getInstance();
    }

    private enum Singleton{
        SINGLETON;
        private EnumMode singleton;

        Singleton(){
            singleton = new EnumMode();
        }

        public EnumMode getInstance(){
            return instance;
        }
    }
}

 


版权声明:本文为yh17388原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。