LintCode-204. 单例

题目

描述

单例 是最为最常见的设计模式之一。对于任何时刻,如果某个类只存在且最多存在一个具体的实例,那么我们称这种设计模式为单例。例如,对于 class Mouse (不是动物的mouse哦),我们应将其设计为 singleton 模式。

你的任务是设计一个 getInstance 方法,对于给定的类,每次调用 getInstance 时,都可得到同一个实例。

样例

例1:

在 Java 中:

    A a = A.getInstance();
    A b = A.getInstance();

a 应等于 b.

解答

思路

一般程序设计中单例模式的实现有两类:

  1. 饿汉式:在程序启动或者单例模式类被加载的时候,单例模式实例就已经被创建好了。
  2. 懒汉式:当程序第一次访问单例模式实例时才进行创建。

如果单例模式实例在系统中经常被用到,可以选择饿汉式,并且它实现起来较为简单;如果单例模式实例在程序中很少用到,就选择懒汉式。

代码

解法一:饿汉式(静态常量)

class Solution {
    /**
     * @return: The same instance of this class every time
     */
    private final static Solution INSTANCE = new Solution();
    
    private Solution(){};
    
    public static Solution getInstance(){
        return INSTANCE;
    }
}

写法简单,在类装载的时候完成实例化,避免了线程同步问题,但是不是懒加载。如果没有使用到该实例,就会造成内存的浪费。

解法二:饿汉式(静态代码块)

class Solution {
    /**
     * @return: The same instance of this class every time
     */
  static{
         instance = new Solution();
     }
     
     private Solution(){}
     
     public static Solution getInstance(){
         return instance;
     }
}

和解法一一样,只不过将类实例化的过程放在了静态代码块,同样在类加载的时候执行静态代码块中的代码。

解法三:懒汉式(线程不安全,单线程使用)

class Solution {
    /**
     * @return: The same instance of this class every time
     */
   private static Solution instance;
     
     private Solution(){}
     
     public static Solution getInstance(){
         if(instance == null){
            instance = new Solution();
         }
         return instance;
     }
}

懒加载,但是在多线程环境下,一个线程计入了if判断句,还往下执行,另一个线程也通过了这个判断语句,会产生多个实例。因此只能在单线程环境下使用这中方式。

解法四:懒汉式(线程安全)

class Solution {
    /**
     * @return: The same instance of this class every time
     */
   private static Solution instance;
     
     private Solution(){}
     
     public static synchronized Solution getInstance(){
         if(instance == null){
            instance = new Solution();
         }
         return instance;
     }
}

用synchronized关键字修饰,将getInstance方法变成线程安全的方法。但是这样在每个线程需要获取实例的时候都要进行同步,如果用到该实例的次数很多,这种写法同步效率很低。

解法五:懒汉式(同步代码块)

class Solution {
    /**
     * @return: The same instance of this class every time
     */
   private static Solution instance;
     
     private Solution(){}
     
     public static Solution getInstance(){
         if(instance == null){
            synchronized (Solution.class) {
                instance = new Solution();
             }
         }
         return instance;
     }
}

根据解法四改进,但是如果创建实例的时候,多个线程同时进入if判断这句话,也会创建多个实例,因此并不能完全保证线程安全。

解法六:双重检查

class Solution {
    /**
     * @return: The same instance of this class every time
     */
     private static volatile Solution instance;
     
     private Solution(){}
     
     public static Solution getInstance() {
         if(instance == null){
             synchronized (Solution.class) {
                 if(instance == null){
                     instance = new Solution();
                 }
             }
         }
         return instance;
     }
};

线程安全,懒加载,效率高。

解法七:静态内部类

class Solution {
    /**
     * @return: The same instance of this class every time
     */
    private Solution(){}
    
    private static class SolutionInstance {
        private static final Solution instance = new Solution();
    }
    
    public static Solution getInstance() {
        return SolutionInstance.instance;
    }
};

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • LintCode-142.O(1)时间检测2的幂次

    悠扬前奏
  • Redis-3. 过期时间

    悠扬前奏
  • LintCode-655.Big Integer Addition

    Given two non-negative integers num1 and num2 represented as string, return the ...

    悠扬前奏
  • Unity开发单例模式防止内存泄漏

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • 细聊冗余表数据一致性(架构师之路)

    本文主要讨论四个问题: (1)为什么会有冗余表的需求 (2)如何实现冗余表 (3)正反冗余表谁先执行 (4)冗余表如何保证数据的一致性 一、需求缘起 互联网很多...

    架构师之路
  • 小程序-优化,部署,细节功能

    ⼩程序默认⼀个缩进=⼀个Tab=2个空格,通常前端开发是⼀个Tab=4个空格,你如果不习惯,可以在设置⾥进⾏设置。

    达达前端
  • 设计模式——Unity通用泛型单例(普通型和继承自MonoBehaviour)

    单例模式是设计模式中最为常见的,不多解释了。但应该尽量避免使用,一般全局管理类才使用单例。

    汐夜koshio
  • 云计算国家标准化工作进入新阶段

    近年来,国内云计算产业发展迅猛,产业环境日益完善,产业规模保持高速增长,但是在云计算产业“火热”的背后,也存在着诸如信息安全、服务质量、权益保障等多种问题。其中...

    静一
  • SpringCloud系列第03节之注册中心Eureka进阶

    Eureka 在设计时,认为分布式环境的网络是不可靠的,可能会出现网络原因导致 EurekaServer 没有收到实例的心跳

    wuweixiang
  • Apache Spark 2.2.0 中文文档

    Apache Spark™ 是一个快速的, 用于海量数据处理的通用引擎. 官方网址: http://spark.apache.org 中文文档: htt...

    片刻

扫码关注云+社区

领取腾讯云代金券