zoukankan      html  css  js  c++  java
  • 单例模式详解

    只能生成一个实例的类是实现了Singleton(单例)模式的类型。实现单例模式的代码比较短,在面试中经常被提及,这篇随笔介绍几种常见的实现方式。

    1.饿汉模式

    这种实现方式优点是没有加锁,执行效率高、线程安全的;但是对象在类加载的时候就会被创建,容易产生垃圾对象,正常情况下使用这种方式来创建单例。具体代码如下:

    public class Singleton {
        // 构造方法私有化 
        private Singleton(){}
        // 类加载就创建实例
        private static Singleton instance = new Singleton();
        // 对外提供获取实例的方法
        public static Singleton getInstance() {  
            return instance;  
        }  
    }

    2.懒汉模式

    最基本的实现方式,线程不安全。

    public class Singleton {
        // 构造方法私有化 
        private Singleton(){}
        // 静态实例
        private static Singleton instance; 
        // 对外提供获取实例的方法,需要的时候再创建实例
        public static Singleton getInstance() {  
            if (instance == null) {
               instance = new Singleton();
            }
            return instance;  
        }  

    3.懒汉模式,线程安全

    这种模式在 getInstance()方法上加了同步锁,当一个线程获取锁来创建实例,那么其他线程只能等待锁被释放。其中一个线程拿到锁后发现实例已经被创建了,就使用已经创建好的实例,效率较低。两种懒汉模式都不推荐使用。

    public class Singleton {
        // 构造方法私有化 
        private Singleton(){}
        // 静态实例
        private static Singleton instance; 
        // 对外提供获取实例的方法,需要的时候再创建实例
        public static synchronized Singleton getInstance() {  
            if (instance == null) {
               instance = new Singleton();
            }
            return instance;  
        }  
    }

    4.双重校验锁(double-checked locking, DCL)

    在实例创建之前我们需要对方法加锁,那么创建以后就无需重复加锁操作,尽最大可能提高程序的执行效率。对上面的代码进行改进,这种方式适用于有特殊需求的场景:

    public class Singleton {
        // 构造方法私有化 
        private Singleton(){}
        // 静态实例
        private static Singleton instance; 
        public static Singleton getInstance() {  
            if (instance == null) {
                // 对Singleton类加锁
               synchronized(Singleton.calss) {
                   if (instance == null) {
                       instance = new Singleton();
                   }
               }
            }
            return instance;  
        }  
    }

    5.静态内部类

    这种方法会在Singleton类内部再创建一个静态内部类,只有显示调用 getInstance()时,实例才会被创建。这种方式适用于静态域需要延迟初始化的场景。

    public class Singleton {
         private Singleton (){} 
         private static class SingletonHolder {
             // final修饰,无法再指向其他对象
             private static final Singleton INSTANCE = new Singleton();
         }
        // 锁定方法,防止子类继承重写方法 
         public static final Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }

     

    参考资料:《Head First 设计模式》

         《剑指offer》第二版

  • 相关阅读:
    ArrayList源代码深入剖析
    java线程基础巩固---wait和sleep的本质区别是什么,深入分析(面试常见问题)
    设计模式相关面试问题-模板方法
    设计模式相关面试问题-适配器
    设计模式相关面试问题-单例
    python-面向对象-10-单例
    python-面向对象-11-异常
    ping
    arp欺骗
    list的方法、操作
  • 原文地址:https://www.cnblogs.com/fly-bryant/p/13252434.html
Copyright © 2011-2022 走看看