zoukankan      html  css  js  c++  java
  • 设计模式(6)单例模式

    单例模式是一个比较简单的设置模式,在我们编码的过程中,有一些类会经常使用到,但是只需要一个实例就可以实现,如果大量的创建实例,可能会导致许多问题,如资源的大量使用、程序异常等。

    这时候就轮到单例模式展现他的力量了。

    单例模式确保了一个类只有一个实例,并提供了一个全局的访问点,下面我们看一个最简单的单例模式。

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

    将对象的构建器属性设置为私有变量,这样他就不会被其他的外部类调用,导致实例化多个对象,同时定一个静态公共方法,用来获取实例,只有在第一次使用的时候才会对其进行创建。

    但是这种单例模式有一个问题,就是在多线程的时候,如果同时两个线程调用getInstance()方法,就会导致程序出现异常,这个时候我们可以稍微简单的改下这个例子,不使用延迟实例,在静态初始化器中创建单例。

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

    这样虽然解决了,线程安全的问题,但是如果这个类在创建和运行时负担比较严重,在程序启动时进行创建,就会使程序启动的缓慢,这时候我们可以用加锁的形式进行单例模式的改造。

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

    这样改造下,就可以避免因为多线程导致单例出现问题。

    还有一种方式,利用内部静态类的方式,也可以解决多线程的问题。

    public class Singleton {
        private static class SingletonHolder {
            private static Singleton singleton = new Singleton();
        }
    
        private Singleton() {
        }
    
        public static Singleton getInstance() {
            return SingletonHolder.singleton;
        }
    }

    在java中还可以利用枚举实现单例模式

    public enum SingletonEnum {
    
        INSTANCE;
    
        public SingletonEnum getInstance() {
            return INSTANCE;
        }
    }

    使用枚举创建单例模式有很多好处

    1. 枚举可解决线程安全问题,比起前面的双重锁校验,代码要精简很多。

    2. 传统的单例模式,如果实现了序列化的接口,就不能够再保持单例了,但是枚举的序列化做了特殊处理,可以解决这些问题。

    单例模式是一种很常用的设计模式,在程序中,涉及到线程池、缓存、对话框、注册表对象、日志对象等,这些只能有一个实例的对象,就可以使用单例模式。

  • 相关阅读:
    json server服务器
    Vue中父子组件通讯——组件todolist
    Vue基础语法
    mac双系统下ubuntu卡在开机密码登录界面卡死
    GBK转UTF8
    Geek/Git中文怎么读
    Javascript正则表达入参是null
    【MySQL】解决You can't specify target table 'user_cut_record_0413' for update in FROM clause
    aglio报错解决
    Sublime美化配置
  • 原文地址:https://www.cnblogs.com/oeleven/p/10507512.html
Copyright © 2011-2022 走看看