前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LintCode-204. 单例

LintCode-204. 单例

作者头像
悠扬前奏
发布2019-05-28 14:41:45
2770
发布2019-05-28 14:41:45
举报
文章被收录于专栏:悠扬前奏的博客

题目

描述

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

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

样例

例1:

代码语言:javascript
复制
在 Java 中:

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

a 应等于 b.

解答

思路

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

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

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

代码

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

代码语言:javascript
复制
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;
    }
}

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

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

代码语言:javascript
复制
class Solution {
    /**
     * @return: The same instance of this class every time
     */
  static{
         instance = new Solution();
     }
     
     private Solution(){}
     
     public static Solution getInstance(){
         return instance;
     }
}

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

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

代码语言:javascript
复制
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判断句,还往下执行,另一个线程也通过了这个判断语句,会产生多个实例。因此只能在单线程环境下使用这中方式。

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

代码语言:javascript
复制
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方法变成线程安全的方法。但是这样在每个线程需要获取实例的时候都要进行同步,如果用到该实例的次数很多,这种写法同步效率很低。

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

代码语言:javascript
复制
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判断这句话,也会创建多个实例,因此并不能完全保证线程安全。

解法六:双重检查

代码语言:javascript
复制
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;
     }
};

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

解法七:静态内部类

代码语言:javascript
复制
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;
    }
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.02.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目
    • 描述
      • 样例
      • 解答
        • 思路
          • 代码
            • 解法一:饿汉式(静态常量)
            • 解法二:饿汉式(静态代码块)
            • 解法三:懒汉式(线程不安全,单线程使用)
            • 解法四:懒汉式(线程安全)
            • 解法五:懒汉式(同步代码块)
            • 解法六:双重检查
            • 解法七:静态内部类
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档