面试的时候经常会问到Java的单例模式,这道题能很好的考察候选人对知识点的理解程度。单例模式要求在系统运行时,只存在唯一的一个实例对象。

下面我们来详细剖析一下其中的关键知识点,并介绍五种实现方法,以及它们的优缺点。

一、最简单的方法是在类加载的时候初始化这个单独的实例。

首先,定义单例类(没有特别的,就是起个名字):

 public class Singleton{

其次,需要定义类变量将单例对象保存下来:

 private static Singleton instance = new Singleton();

这里需要注意两点:

  1. private:除了Singleton类内部,其它地方无法访问该变量;

  2. static:确保是静态类变量,这样可以通过类名来访问,无须实例;

再次,需要显式定义构造函数,并将其设置为private,这样在Singleton类之外new的话编译器就会报错,即使是Singleton的子类也不行:

 private Singleton() {}

最后,定义单例对象的获取方法,

 public static Singleton getInstance() {
return instance;
}

同样需要注意:

  1. public:这样外部才能调用;

  2. static:这样外部才能通过类名来访问,否则获取不到单例对象;

二、使用懒加载。在方法一的基础上,我们需要修改几处代码:

首先,静态类变量应该初始化为NULL:

 private static Singleton instance = NULL;

其次,getInstance()方法需要承担生成实例的任务:

 public static Singleton getInstance() {
if(instance == NULL)
instance = new Singleton();
return instance;
}

三、考虑多线程的问题。方法二在多线程情况下仍然有可能产生多个实例,我们需要使用同步来避免多线程问题。如下,在getInstance()方法前使用synchronized关键字:

 public static synchronized Singleton getInstance() {

四、考虑性能问题。synchronized关键字修饰getInstance()方法,会导致所有调用getInstance()方法的线程都要竞争同一把锁,即使在单例对象已经生成好的情况下。这里使用double check的方式。另外,还需要注意instance在初始化过程中,可能已经不为NULL,这样有可能会导致程序崩溃,因此这里加了个临时变量t,确保初始化完成之后再赋值给instance。

public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null){
Singleton t = new Singleton();
instance = t;
}
}
}
return instance;
}

五、更简化的方法。基于静态内部类的特性,我们可以利用它的懒加载机制简化实现:

 public static Singleton getInstance(){
return NestedClass.instance;
} private static class NestedClass{
private static Singleton instance = new Singleton();
}

五种方法实现Java的Singleton单例模式的更多相关文章

  1. Java 字符串拼接 五种方法的性能比较分析 从执行100次到90万次

    [请尊重原创版权,如需引用,请注明来源及地址] > 字符串拼接一般使用“+”,但是“+”不能满足大批量数据的处理,Java中有以下五种方法处理字符串拼接,各有优缺点,程序开发应选择合适的方法实现 ...

  2. Java:判断字符串是否为数字的五种方法

    Java:判断字符串是否为数字的五种方法 //方法一:用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = str. ...

  3. java:JavaScript2:(setTimeout定时器,history.go()前进/后退,navigator.userAgent判断浏览器,location.href,五种方法获取标签属性,setAttribute,innerHTML,三种方法获取form表单信息,JS表单验证,DOM对象,form表单操作)

    1.open,setTimeout,setInterval,clearInterval,clearTimeout <!DOCTYPE> <html> <head> ...

  4. 两个变量交换的四种方法(Java) 七种方法(JS)

    两个变量交换的四种方法(Java)   对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) 1 class TestEV 2 ...

  5. Android之数据存储的五种方法

    1.Android数据存储的五种方法 (1)SharedPreferences数据存储 详情介绍:http://www.cnblogs.com/zhangmiao14/p/6201900.html 优 ...

  6. js去掉字符串前后空格的五种方法

    转载 :http://www.2cto.com/kf/201204/125943.html 第一种:循环检查替换[javascript]//供使用者调用  function trim(s){  ret ...

  7. EntityFramework嵌套查询的五种方法

    这样的双where的语句应该怎么写呢: var test=MyList.Where(a => a.Flows.Where(b => b.CurrentUser == “”) 下面我就说说这 ...

  8. 实现sticky footer的五种方法

    2017-04-19 16:24:48 什么是sticky footer 如果页面内容不够长的时候,页脚块粘贴在视窗底部:如果内容足够长时,页脚块会被内容向下推送. 用position实现? 如果是用 ...

  9. linux 清空catalina.out日志 不需要重启tomcat(五种方法)【转】

    1.重定向方法清空文件   [root@localhost logs]# du -h catalina.out  查看文件大小17M catalina.out[root@localhost logs] ...

随机推荐

  1. memsql 6.7集群安装

    预备环境处理 安装yum 源 yum install -y yum-utils yum-config-manager --add-repo https://release.memsql.com/pro ...

  2. ORA-01791: not a SELECTed expression

    Student表有3个字段:id,name,age 看这两个SQL语句 (1)select name from student order by id; (2)select distinct(name ...

  3. python、java大作战,python测试dubbo接口

    很多小伙伴都反映公司要求测dubbo(dubbo是一个java的分布式开源框架)接口,不会写java代码,怎么测,能不能用python来调dubbo接口.当然是可以的了,最近研究了一下,很简单,分享给 ...

  4. azkaban:java任务调度系统

    github:https://github.com/azkaban/azkaban 官方网站:https://azkaban.github.io/ 好的介绍文章:http://srcct.com/20 ...

  5. POJ2955Brackets——dp

    题目:http://poj.org/problem?id=2955 1.考虑区间. 2.当前区间可为自己子区间的和(题意果然是和而非最大值). 3.考虑当前区间的边界. #include<ios ...

  6. android调节音量——AudioManager的应用

    Android中可以通过程序获取系统手机的铃声和音量.同样,也可以设置铃声和音量.android中给出了AudioManager类来实现音量获取.音量控制. 本篇基于 Android API 中的 A ...

  7. R(8): tidyr

    tidy(整洁),Tidyr包是由Hadely Wickham创建,这个包提高了整理原始数据的效率,tidyr包的4个常用的函数及其用途如下: gather()——它把多列放在一起,然后转化为key: ...

  8. springMVC参数绑定JSON类型的数据

    需求就是: 现在保存一个Student,并且保存Student的friend,一个student会有多个朋友,这里要传递到后台的参数是: var friends = new Array(); var ...

  9. Discuz论坛管理的问题汇总

    Discuz论坛在Linux上搭建成功了, 不得不说, 其功能是非常强大的, 可以满足已知的绝大多数的需求. 搭建完成后也有一些问题, 在这里汇总一下, 以便将来查阅. 1. 显示未处理用户信息, 但 ...

  10. java中使HttpDelete可以发送body信息

    java中使HttpDelete可以发送body信息RESTful api中用到了DELETE方法,android开发的同事遇到了问题,使用HttpDelete执行DELETE操作的时候,不能携带bo ...