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》第二版

  • 相关阅读:
    POJ 2240 Arbitrage spfa 判正环
    POJ 3259 Wormholes spfa 判负环
    POJ1680 Currency Exchange SPFA判正环
    HDU5649 DZY Loves Sorting 线段树
    HDU 5648 DZY Loves Math 暴力打表
    HDU5647 DZY Loves Connecting 树形DP
    CDOJ 1071 秋实大哥下棋 线段树
    HDU5046 Airport dancing links 重复覆盖+二分
    HDU 3335 Divisibility dancing links 重复覆盖
    FZU1686 神龙的难题 dancing links 重复覆盖
  • 原文地址:https://www.cnblogs.com/fly-bryant/p/13252434.html
Copyright © 2011-2022 走看看