• 面试笔记之手写单例模式


    1. 前言

    今天面试前,笔试中遇到写单例模式的试题,之前也参考一些优秀博主的博客写过一遍。
    在此,再次整理一下。

    2. 单例模式要点

    实现单例模式有以下三个要点:
    1)首先要确保全局只有一个类的实例:要保证这一点,至少类的构造器要私有化
    2)单例的类只有自己创建自己:因为构造器私有了,但还要有一个实例,只能自己创建咯
    3)单例类必须能够提供自己的唯一的实例给其他类:就要有一个公共的方法能返回该实例类的唯一实例

    3. 单例类的实现

    单例类的实现有以下6种(两种饿汉式,两种懒汉式,双重校验锁及静态内部类):

    具体介绍及实现如下:

    1)饿汉式——静态常量方式(线程安全)
    该方式在类加载时就初始化,天然线程安全
    实现代码如下(注意使用了static):

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

    2)饿汉式——静态代码块方式(线程安全)

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

    3)懒汉式(线程不安全)
    第一次调用才初始化,实现了懒加载特性,多线程禁用

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

    4)懒汉式(线程安全)
    方法加上同步锁,相较于3性能会有折损,但也还好

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

    5)双重校验锁(线程安全,效率高)
    注意volatile的使用,保证了各线程对singleton静态实例域修改的可见性

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

    6)静态内部类实现单例(线程安全,效率高)
    这种情况下Singleton被装载了,instance不一定被初始化。
    因为SingleHolder类没有被主动使用,只有通过显示调用getInstance方法时,才会显式装载SingleHolder类,从而实例化instance。
    注意内部类SingleHolder要用static修饰,且其中静态变量INSTANCE必须是final的

    public class Singleton {
        private static class SingleHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
        private Singleton() {}
        public static Singleton getSingleton() {
            return SingleHolder.INSTANCE;
        }
    }
    

    参考链接:https://www.cnblogs.com/happyone/p/11221157.html

    步履不停
  • 相关阅读:
    c语言中的增量与减量········不要太聪明
    存储器··············RAM,SRAM,EEPROM 等等
    对于 sizeof(char)的一些零碎······
    C语言中float,double等类型,在内存中的结构
    同步异步存储器
    Linux的帧缓冲设备(Framebuffer)简介
    嵌入式 c 中结构体经常碰到_I、 __O 、__IO是什么意思?
    新型的按键扫描程序
    数据结构
    jQuery(八)选择器与选择方法
  • 原文地址:https://www.cnblogs.com/yuanyunjing/p/15426191.html
Copyright © 2020-2023  润新知