设计模式——单例模式

单列模式

整个系统中只有一个实例存在。

一、单列模式的实现方式
  • 饿汉模式

    public class Singleton{
        private static final Singleton instance = new Singleton();//自己创造自己,保证唯一不可变
        private Singleton(){}//构造方法私有化
        public static Singleton getInstance(){ //对外暴露接口,以调用这个单列
            return instance;
        }
    }
    

    程序一开始便会创建一个实例 ,如果一直没有使用它,会造成一定的内存资源浪费。

  • 懒汉模式

    1. 简单实现
    public class Singleton{
        private static Singleton instance;//不实例化
        private Singleton(){};
        public static Singleton getInstance(){
            if( instance == null ){//如果实例为空则创建一个实例
                instance = new Singleton();
            }
            return instance;
        }
    }
    

    不足:当有多个同时请求时,可能会造成创造出多个实例。

    1. 在方法上加synchronized同步,保证只有一个实例产生
    public class Singleton{
        private static Singleton instance;
        private Singleton(){};
        public static synchronized Singleton getInstance(){
            if( instance == null ){//如果实例为空则创建一个实例
                instance = new Singleton();
            }
            return instance;
        } 
    }
    
    1. 在方法内加synchronized同步(双层检查),避免造成资源浪费
    public class Singleton{
        private static volatile Singleton instance;
        private Singleton(){};
        public static Singleton getInstance(){
            if( instance == null ){//如果实例为空则创建一个实例
                sysnchronized(Singleton.class){
                    if(instance == null ){
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        } 
    }
    
  • 静态内部类

    public class Singleton{
        private Singleton(){};
        //声明一个静态内部类
        private static class SingletonInstance {
            private static final Singleton INSTANCE = new Singleton();
        }
        //提供一个共有方法,调用返回内部类
        public static Singleton getInstance(){
            return SingletonInstance.INSTANCE;
        }
    }
    

    说明:

    • ①使用静态内部类可以保证延迟加载,且保证线程安全。因为静态内部类在外部类Singleton初始化时不会立刻实例化,而是在调用getInstance方法时才会装载内部的静态类,完成实例化。
    • ②类的静态属性只会在第一次加载类的时候初始化,在这里,JVM帮助我们保证了线程的安全性,在类初始化时,其他的类时无法进入的。
  • 枚举模式

    public class SingletonTest{
        public static void main(String[] args){
            Singleton instance = Singleton.INSTANCE;
        }
    } 
    enum Singleton{
    	INSTANCE;
    }
    

    说明:此方法可以避免多线程同步问题,而且还能防止反序列化重新创建新的对象。

二、单列模式在JDK中的应用

​ 在JDK中java.lang.Runtime使用到了单列模式的饿汉式。

原文地址:https://www.cnblogs.com/Mhang/p/12408647.html