美文网首页Java高级进阶
面试中的单例问题

面试中的单例问题

作者: java菜 | 来源:发表于2018-11-01 18:23 被阅读0次

当我兴冲冲的带着笔记答案参加面试时,突然发现面前的面试官显得很严肃而且眉头紧锁,不知道是工作太累了,还是说他对今天的面试官不是很满意。

于是我就勇敢的坐过去在他的面前坐了下来,没想到第一道题就让面试官看出了我的水平,因此今天跟大家聊聊面试中单例的问题,希望大家都能了解这块内容。

在早期的项目代码中,如果我们想使用类的某个方法,我们基本都会创建一个类的对象实例然后再调用方法,这样的实现往往在系统内就会存在某个类的大量实例。如此一来,项目框架很难管理大量的对象,而且如果java虚拟机不能及时回收,容易造成内存溢出。

首先我们要明白什么是单例,所谓单例就是说在项目框架内某个类的对象实例只存在一个,任何调用方获取到的对象实例都是一个,那么很明显这个类是不能够被外部直接调用类构造器创建的。

我们先看下一个简单的单例设计:

上面代码在单线程是没有问题的,而且只有当线程调用类的静态方法时,才会生成类的静态变量。但是当多线程访问时,上面代码是有问题的,会生成多个对象的实例。

那么,我们可以用另外一种方法实现,比如说在类加载时候就初始化对象的实例,这样后面无论怎么调用类静态方法都不创建新的实例。还有一种方法,但是会牺牲部分系统性能,意思就是在多线程访问方法时通过锁机制让线程排队访问。我们先通过在类方法上加锁来实现类的单例,比如:

上述方法能实现单例,而且采用的思路是延迟加载,但是执行效率比较低。

之前有看到部分同学使用双重锁(Double CheckLock)机制来实现单例模式,一方面需要在实例上加上volatile关键字通知操作系统实现线程访问时内存屏障,然后还需要在方法中通过虚拟机实现的synchronized来同步方法访问,写法如下:

反正,我认为上面的实现是比较复杂的,大家需要去了解的知识点比较多,比如volatile ,synchronized,内存屏障。因此我不建议大家用这种方式,可以作为技术了解下还是有好处的,毕竟如果能跟面试官探讨到这一步,还是会加一些分的。

如果说我们不考虑服务负载问题,在多线程环境下可以预先加载类的静态实例,当虚拟机加载完成类后就会创建类的静态变量,甭管你到时用不用,反正给你留在那里。所有线程访问到的都是同一静态实例,有人也称这种方式为饿汉式,具体写法如下:

上面写法实现单例也是没有问题的,但是有些同学就会觉得如果我只是想调用一个类的某个静态方法,并不想生成它的实例,那有没有其他方法呢,经过各路大神的指点结合自身的总结,可以使用内部静态类来实现这个需求。

开发的同学都知道,虚拟机在加载类的过程中一开始并不会初始化类的内部静态类。如果线程调用内部静态类时,虚拟机只会初始化一次,这样既可以实现单例,同时也是线程安全的。具体写法如下:

除了以上讲到的几种方式外,JDK自身的枚举类型本身就是单例的实现,调用者不能显式的调用构造器完成实例创建,因此很多Java规范文档推荐使用枚举来实现单例。

当然对于初级开发人员而言,现在的主流开发框架都提供单例/多例模式供开发者选择,这样的好处让开发者更多关注业务功能开发,而不用过多关注虚拟机内部类实例创建问题。例如spring中默认类注入就是单例的,可以根据实际情况设置scope为singleton(单例)或者prototype(多例),如下图所示:

由于本人技术水平还有很大的上升空间,文中存在讲述不清楚或者错误的地方,请大家批评指正。

欢迎工作一到五年的Java工程师朋友们加入Java架构开发: 854393687

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

相关文章

  • 面试中的单例问题

    当我兴冲冲的带着笔记答案参加面试时,突然发现面前的面试官显得很严肃而且眉头紧锁,不知道是工作太累了,还是说他对今天...

  • 关于 "单例" 的一些小事

    本篇文章要讲解的是关于单例模式的一些问题。无论是在面试或是在工作中我们都会使用到单例这种设计模式,实现单例的方式有...

  • volicate、单例模式、jvm内存模型联系

    面试中,面试官问起单例模式时,我们是否只乖乖地回答了七种单例模式呢 七种单例模式实现 在单例模式的懒汉模式(线程安...

  • 剑指offer面试题2:实现Singleton模式

    实现单例模式应该是面试中比较常见的问题,下面简单讲讲几种单例模式的实现方式。 饿汉式 优点:避免线程同步产生的问题...

  • Android 丨 单例模式

    面试过程中,单例模式总是会被问及,所以抽时间总结了一份单例相关的笔记 单例概念 单例模式是一种对象的创建模式,它用...

  • 美团面试官问:写一个你认为最好的单例模式?于是我写了7个

    面试题:写一个你认为最好的单例模式 面试考察点 考察目的: 单例模式可以考察非常多的基础知识,因此对于这种问题,很...

  • Java面试之单例模式浅谈

    单例模式是Java面试中常会问到的一个问题,众所周知,单例模式分为两大部分:饿汉模式和懒汉模式。但是,如果当面试官...

  • 单例模式详解

    单例模式是最常用的设计模式之一,不管是工作中,还是面试中,单例模式一直都是宠儿。单例模式看似简单,但是如果深入理解...

  • Java基础系列-单例的7种写法

    原创文章,转载请标注出处:《Java基础系列-单例的7种写法》 一、概述 Java中单例有7种写法,这个是在面试中...

  • Swift单例模式

    Swift单例模式 单例模式 单例模式的作用是解决“应用中只有一个实例”的一类问题。在Cocoa Touch框架中...

网友评论

    本文标题:面试中的单例问题

    本文链接:https://www.haomeiwen.com/subject/bpsztqtx.html