面试官系统之设计模式(单例模式)

原创 2018年04月15日 17:18:23

单例模式:

顾名思义就是只能有一个,不能在出现第二个。就如同地球上没有两片完全一模一样的树叶一样。

程序猿的角度理解:一个类有且只能有一个实例,不能出现第二个,并且整个项目系统中都能访问该实例。

面试官:为啥不能出现第二个?

程序猿:。。。(这个面试官是笨蛋,出现第二个那就不叫单例模式了,那至少得叫双例模式,是吧?)

面试官:为啥整个项目系统中都能访问该实例?

程序猿:不能访问该实例,那new出来还有什么意义。

面试官:那你给我写个单例模式吧

程序猿:写就写,这能难倒我,哼,先写个懒汉式单例(第一种

package com.tang.study.singleton;

/**
 * 单例模式
 * 懒汉式单例
 * Created by tgp on 2018/4/15.
 */
public class SingletonPatternOne {

    //关键点0:构造函数是私有的
    private SingletonPatternOne(){}

    ///关键点1:声明单例对象是静态的
    private static SingletonPatternOne instance  = null;

    //通过静态方法来构造对象
    public static SingletonPatternOne getInstance(){
        if(instance == null){//关键点2:判断单例对象是否已经被构造
            instance = new SingletonPatternOne();
        }
        return instance;
    }

    public void showMessage(){
        System.out.println("懒汉式单例:啥时候用啥时候NEW。");
    }

}

面试官:你这代码遇到多线程的并发条件下就不安全了吧。在if判断那里,如果两个线程同时访问,有可能给new出多个单例实例,都多个了,还是屁的“单例”啊。

程序猿:(额,好像也是,幸亏我还有点干货,再撸一段),那我给您再写一段(第二种

/**
 * 单例模式
 * 饿汉式单例
 * Created by tgp on 2018/4/15.
 */
public class SingletonPatternTwo {

    //关键点0:构造函数是私有的
    private SingletonPatternTwo(){
    }

    ///关键点1:声明单例对象是静态的
    private static SingletonPatternTwo instance  = new SingletonPatternTwo();

    //通过静态方法来构造对象
    public static SingletonPatternTwo getInstance(){
        return  instance;
    }

    public void showMessage(){
        System.out.println("饿汉式单例:管你用不用,我都先给你new出来,用不用是你的事,一劳永逸,省的你每次用时都来烦我。");
    }
面试官:那你给我讲讲你写的这种单例模式的优缺点

程序猿:

   优点:这种写法在类加载的时候就完成对象的实例化,避免了线程不安全的问题。

   缺点:在类加载的时候就完成了实例化,如果这个类一直没用,就会造成内存的浪费。

面试官:这种方式是解决了线程不安全的问题,但内存浪费总是不太好吧,尤其是服务器的内存都是很贵的

程序猿:好吧,那我给您优化优化第三种

public class SingletonPatternThree {

    //关键点0:构造函数是私有的
    private SingletonPatternThree(){}

    ///关键点1:声明单例对象是静态的
    private static SingletonPatternThree instance  = null;

    //通过静态方法来构造对象
    public static synchronized SingletonPatternThree getInstance(){
        if(instance == null){//关键点2:判断单例对象是否已经被构造
            instance = new SingletonPatternThree();
        }
        return instance;
    }

    public void showMessage(){
        System.out.println("懒汉式加锁:第一次调用才初始化,避免内存浪费,同时线程安全");
    }
}
面试官:内存浪费和线程安全的问题都解决了,那方法加锁会影响效率,多线程的情况,第一个访问方法期间,其它用户只能等待,用户体验太差

程序猿:(有完没完了。。)逼我放大招第四种:双重检查)

 //通过静态方法来构造对象
    public static SingletonPatternFour getInstance(){
        if(instance == null){//关键点2:判断单例对象是否已经被构造
            synchronized(SingletonPatternFour.class){//关键点3:加锁
                if(instance == null){//关键点4:二次判断单例是否已经被构造
                    instance = new SingletonPatternFour();
                }
            }
        }
        return instance;
    }

    public void showMessage(){
        System.out.println("进行了两次if (instance == null)检查,这样就可以保证线程安全了。" +
                "这样,实例化代码只用执行一次,后面再次访问时,判断if (instance == null),直接return实例化对象。");
    }

面试官:这种不错,那你还会其它的实现方法吗?

程序猿:(我会的可多了,都拿出来怕吓着你)我还会几种别的第五种:静态内部类

public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}
程序猿:类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。

优点:避免了线程不安全,延迟加载,效率高。

第六种:枚举

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
} 
经验之谈:一般情况下,推荐双检锁方式和静态内部类。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37742084/article/details/79950045

设计模式之单例模式详解与应用

-
  • 1970年01月01日 08:00

SSH中用到的设计模式之一——单例模式

这期主要是总结并复习一下ssh框架中底层代码中用到的设计模式(学习这些设计模式是需要一些基础的,如果没有开发过一些小的项目,建议还是先实际敲敲代码再来看)实际上这些框架也就是用来解决开项目效率低而由前...
  • cc6208048
  • cc6208048
  • 2014-10-22 22:23:02
  • 1126

设计模式系列(一)单例模式

一、简单介绍 单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。 《设计模式》书中对单例模式动机的介绍 对于系统中的某些类...
  • robertcpp
  • robertcpp
  • 2016-06-05 11:00:42
  • 3641

设计模式练习--单例模式

参 考:  http://www.runoob.com/design-pattern/singleton-pattern.html        单例模式(Singleton Pat...
  • m0_37676632
  • m0_37676632
  • 2017-05-23 22:12:56
  • 192

设计模式之——单例模式(Singleton)的常见应用场景

单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此...
  • likika2012
  • likika2012
  • 2013-09-09 16:43:32
  • 51078

设计模式之单例模式

  • 2017年12月01日 17:54
  • 9KB
  • 下载

单例模式之多例类【设计模式】

单例模式:单例模式 多例类:请使用单例模式编写一个程序,然后考虑一下如何对这个程序进行改造,使得系统中某个类的对象可以存在有限多个,例如两例或三例? 法一:最多有max_num种实例,如果调用...
  • lin14543
  • lin14543
  • 2017-02-28 16:02:29
  • 1015

调侃《Head First 设计模式》之单例模式

对于一个类来说,平常我们可以随便new出无限多个对象(只要内存hold得住),但是像线程池、缓存、对话框、日志对象、设备驱动程序的对象只能有一个对象,如果制造多个实例就会出现问题。比如程序行为异常,资...
  • sinat_23092639
  • sinat_23092639
  • 2015-04-25 11:02:27
  • 730

Java设计模式之一 单例设计模式

设计模式: 设计模式的概念首先来源于其它行业:建筑业,在早起建房子的时候,肯定是经验缺乏、显得杂乱无序的,这就会造成很多问题,在行业发展过程,通过不断的经验积累,前辈们针对这些问题提出了合理解决方案...
  • qq_32736689
  • qq_32736689
  • 2016-04-07 08:29:45
  • 2555

设计模式(二)单例模式的七种写法

面试的时候,问到许多年轻的Android开发他所会的设计模式是什么,基本上都会提到单例模式,但是对单例模式也是一知半解,在Android开发中我们经常会运用单例模式,所以我们还是要更了解单例模式才对。...
  • itachi85
  • itachi85
  • 2016-01-17 10:29:15
  • 25014
收藏助手
不良信息举报
您举报文章:面试官系统之设计模式(单例模式)
举报原因:
原因补充:

(最多只允许输入30个字)