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

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

  • 相关阅读:
    海选女主角
    发工资咯:)
    绝对值排序
    数列有序!
    母牛的故事
    一文看懂外汇风险准备金率调整为 20%的含义
    1080i减少带宽
    为什么要采用隔行扫描?
    720P、1080P、4K是什么意思?
    VBR一次編碼 v.s 二次編碼(VBR 1-pass vs 2-pass)
  • 原文地址:https://www.cnblogs.com/oeleven/p/10507512.html
Copyright © 2011-2022 走看看