面试的时候经常会问到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. lets encrypt 申请nginx 泛域名

    1. 安装certbot工具 wget https://dl.eff.org/certbot-auto chmod a+x ./certbot-auto 2. 申请通配符域名 ./certbot-au ...

  2. sql server merge into 与update 批量更新1 百万测试数据的性能比较

    1. 1百万的测试数据的生成 declare @index int;  begin  set @index=0;  while @index<1000000  begin  insert int ...

  3. .NET基金会成立

    作者 Jonathan Allen ,译者 臧秀涛 发布于 2014年4月8日 随着.NET基金会的成立,微软在成为主要的开源参与者的道路上又前进了一步.该基金会的宗旨是“成为越来越多的开源.NET项 ...

  4. oracle归档日志配置查询

    归档日志(Archive Log)是非活动的重做日志备份.通过使用归档日志,可以保留所有重做历史记录,当数据库处于ARCHIVELOG模式并进行日志切换式,后台进程ARCH会将重做日志的内容保存到归档 ...

  5. 洛谷2014选课(树型dp)

    题目:https://www.luogu.org/problemnew/show/P2014 千万注意遍历 j 和 k 的边界! 0点很好用. siz很好用. #include<iostream ...

  6. 【转】ORACLE Dataguard安装

    ORACLE Dataguard安装 标签: oracledatabasearchivesql数据库list 2011-08-01 09:40 5548人阅读 评论(1) 收藏 举报  分类: ORA ...

  7. Windows10安装.net3.5

    1.装载windows10映像 2.运行如下命令(注意修改盘符): Dism /online /enable-feature /featurename:NetFX3 /All /Source:F:\s ...

  8. 利用springMVC包装类上传多个文件

    前端JSP页面代码片段: <!-- springMVC包装类上传文件 --><form name="uploadFiles" id="uploadFil ...

  9. spring SOA architecture

    在谈这个之前,还得再说下SOA和平台.SOA做两件事情,一个是解耦并识别可重用的服务,一个是对服务进行灵活组装和编排满足业务需求,SOA核心是业务和技术的解耦,服务和能力的复用.而在IT领域的平台平台 ...

  10. js例子记载

    1.获取项目路径的,不一定有用,仅作参考用: function getRootPath() { var curWwwPath = window.document.location.href; //&q ...