zoukankan      html  css  js  c++  java
  • 面试笔记之手写单例模式

    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

    步履不停
  • 相关阅读:
    LintCode-Search for a Range
    LintCode-Serialization and Deserialization Of Binary Tree
    LeetCode-Reverse Words in a String
    LeetCode-Reorder List
    LeetCode-Word Break
    LeetCode-Word Ladder
    LeetCode-Valid Palindrome
    cf div2 237 D
    POJ 1759
    cf div2 238 D
  • 原文地址:https://www.cnblogs.com/yuanyunjing/p/15426191.html
Copyright © 2011-2022 走看看