美文网首页
设计模式之单例模式

设计模式之单例模式

作者: 逍遥白亦 | 来源:发表于2020-12-26 11:45 被阅读0次

    单例模式

    定义

    指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。

    特点

    1. 单例类只有一个实例对象
    2. 该单例对象必须由单例类自行创建;
    3. 单例类对外提供一个访问该单例的全局访问点;

    结构

    主要角色

    1. 单例类:包含一个实例且能自行创建这个实例的类
    2. 访问类:使用单例的类

    类图

    实现

    懒汉式单例

    package Singleton;
    
    /**
     * 懒汉式
     * 保证只有类在用到时才加载,注意线程安全
     * 由于加锁,性能会下降
     */
    public class LazySingleton {
    
        private static volatile LazySingleton instance;
    
        private LazySingleton() {};
    
        public static synchronized LazySingleton getInstance(){
            if (instance == null){
                instance = new LazySingleton();
            }
    
            return instance;
        }
    
    }
    
    

    饿汉式单例

    package Singleton;
    
    /**
     * 饿汉式
     * 类加载到内存后,就实例化一个单例,JVM保证线程安全
     * 简单实用,推荐使用
     * 唯一缺点:不管用到与否,类加载时就完成实例化
     */
    public class HungrySingleton {
    
        private static final HungrySingleton instance = new HungrySingleton();
    
        private HungrySingleton() {};
    
        public static HungrySingleton getInstance() {
            return instance;
        }
    
        public static void main(String[] args){
            HungrySingleton h1 = HungrySingleton.getInstance();
            HungrySingleton h2 = HungrySingleton.getInstance();
            System.out.println(h1 == h2);
    
        }
    
    }
    
    

    静态内部类实现

    package Singleton;
    
    /**
     * 静态内部类
     * JVM保证单例
     * 加载外部类时不会加载内部类,这样可以实现懒加载
     */
    public class InnerStaticSingleton {
    
        private InnerStaticSingleton() {};
    
        private static class InnerStaticSingletonHolder{
            private static final InnerStaticSingleton INSTANCE = new InnerStaticSingleton();
        }
    
        public static InnerStaticSingleton getInstance(){
            return InnerStaticSingletonHolder.INSTANCE;
        }
    
        public static void main(String[] args){
            for (int i=0; i<100; i++){
                new Thread( () -> System.out.println(InnerStaticSingleton.getInstance().hashCode())).start();
            }
        }
    
    }
    
    

    Java创始人推荐的写法

    package Singleton;
    
    /**
     * Java创始人之一在Effective in Java中的写法
     * 保证线程安全,也保证反序列化,因为枚举类没有构造方法,无法构造出实例
     */
    public enum NBSingleton {
    
        INSTANCE;
    
        public static void main(String[] args){
            for (int i=0; i<100; i++){
                new Thread( () -> System.out.println(NBSingleton.INSTANCE.hashCode())).start();
            }
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:设计模式之单例模式

          本文链接:https://www.haomeiwen.com/subject/eitgnktx.html