当前位置: 移动互联网学院 > Java培训 > JAVA开发 > Java如何实现单例模式
Java如何实现单例模式 时间:2017-05-16     来源:华清远见JAVA学院

今天要为大家分享的是Java如何实现单例模式。

Java如何实现单例模式

1、前言

经常同事在一起聊单例模式,所在项目中也是各种方式实现的单例模式,有的还是漏洞百出,各种面试也会问到,可是真的细究发现自己并没有一个完善的认识,今天就单例模式整理下。

2、什么是单例模式

单例对象的类必须保证只有一个实例存在——这是维基百科上对单例的定义,这也可以作为对意图实现单例模式的代码进行检验的标准。

对单例的实现可以分为两大类——懒汉式和饿汉式,他们的区别在于:懒汉式:指全局的单例实例在第一次被使用时构建。饿汉式:指全局的单例实例在类装载时构建。

从它们的区别也能看出来,日常我们使用的较多的应该是懒汉式的单例,毕竟按需加载才能做到资源的大化利用嘛~

3、懒汉式单例

经常会问应聘者:“知道设计模式,简单介绍下?”应聘者:“单例模式.....就是JVM中保持只有一个的实例,实现方式就是把构造方法私有,自己实现一个获取方法.....”。嗯,看来大家的单例模式都是懒汉式了。那就先讲讲懒汉式吧,其实不管怎么个实现,还是那句话--为了保证单例对象的类必须只有一个实例存在。那下面就谈谈懒汉式的演变。

3.1Java实现单例模式的简单版本

看简单的写法Version 1:

/**

* 简单版本的单例模式

* Created by zhangyhk on 2017/5/16.

*/

public class Single1 {

private static Single1 instance;

public static Single1 getInstance(){

if(null==instance){

instance = new Single1();

}

return instance;

}}

或者再进一步,把构造器改为私有的,这样能够防止被外部的类调用。

/**

* 简单版本的单例模式

* 构造方法私有

* Created by zhangyhk on 2017/5/16.

*/

public class Single1 {

private static Single1 instance;

private Single1(){};

public static Single1 getInstance(){

if(null==instance){

instance = new Single1();

}

return instance;

}}

每次获取instance之前先进行判断,如果instance为空就new一个出来,否则就直接返回已存在的instance。这种写法在大多数的时候也是没问题的。问题在于,当多线程工作的时候,如果有多个线程同时运行到if (instance == null),都判断为null,那么两个线程就各自会创建一个实例——这样一来,就不是单例了。

3.2 synchronized版本

既然可能因为多线程有问题,那么就加锁吧,java处理多线程问题,就是加锁,在大多数情况下都是“synchronized”关键字,我经常会问StringBuilder和StringBuffer哪个是线程安全的?为什么?大多数会回答StringBuffer可是“为什么?”都回答的不是很好,其实JDK里大部分的线程安全实现方式都是加“synchronized”,当然还有别的实现方式这里就不详细说了。

修改后的代码如下,相对于Version1.1,只是在方法签名上多加了一个synchronized:

/**

* 简单版本的单例模式

* Created by zhangyhk on 2017/5/16.

*/

public class Single2 {

private static Single2 instance;

private Single2(){};

public static synchronized Single2 getInstance(){

if (null==instance){

instance = new Single2();

}

return instance;

}}

X