单例模式是算是java常见的23中设计模式中最常用、也是最简单的一种设计模式了;其核心思想是确保一个类的对象在内存中有且只有一个,这个对象的所有属性的值在内存中始终保持一致性,调用者只能获取这个实例修改里面的内容,并不能创建该类的新的实例。在java里面如果我们要创建一个对象的实例,最常用的方法就是通过其构造方法创建,创建一个类,java默认的会有一个空参数的构造方法;如果,我们不想让调用者创建该类的对象,则需要将这个默认的空参数的构造方法私有化,但是为了能获取到该类的对象实例,则这个类需要对外提供获取该类对象实例的方法。因此,可以总结java实现单例模式的做法和步骤如下:1、私有化类的构造方法,不让调用者通过构造方法创建该类的对象实例;2、自己内部维护一个私有的对象实例;3、对外提供获取该对象实例的方法。按照上面的思想,以下就是java实现单例模式的一种方式:
package com.summerxia.single;
/**
* 类描述: 单例模式类
* 项目名称: SingleInstance
* 类名称: Single
* 创建人: xhl
* 创建时间: 2015-7-4 下午5:32:45
* 版本: v1.0
*/
public class Single {
/**
* 内部维护的一个类的对象实例
*/
private static Single instance = new Single();
/**
* 私有化构造方法,
*/
private Single(){}
/**
* 对外提供获取内部对象实例的方法
* @return 该类的内部对象实例
*/
public static Single getInstance(){
return instance;
}
}
这里对外提供获取该对象的方法使用了static修饰,这样可以直接通过类名直接调用该方法,获取到类的对象实例;
单例模式存在两种实现方式:饿汉式和懒汉式;以上的代码实现方式就是饿汉式,既该类不管外部需不需要改类的对象实例,自身先创建一个对象实例,当调用者需要的时候再提供给调用者;就好像一个饥饿的人一样,不管需不需要我先吃饭再说;懒汉式同饿汉式正好相反,懒汉式比较懒,不会先创建对象,只有当调用者需要用到该类的对象时才会创建类的对象实例,并返回给调用者;以下是用懒汉式实现的单例:
package com.summerxia.single;
/**
* 类描述: 单例模式类
* 项目名称: SingleInstance
* 类名称: Single
* 创建人: xhl
* 创建时间: 2015-7-4 下午5:32:45
* 版本: v1.0
*/
public class Single {
/**
* 内部维护的一个类的对象实例
*/
private static Single instance;
/**
* 私有化构造方法,
*/
private Single(){}
/**
* 对外提供获取内部对象实例的方法
* @return 该类的内部对象实例
*/
public static Single getInstance(){
if(instance == null){
instance = new Single();
}
return instance;
}
}
在懒汉模式中,一开始只是声明了该类的实例,并没有创建该类的实例,只有调用者在调用方法getInstance时判断对象实例是不是为null,如果为null则创建对象实例,如果不为null,则直接返回对象实例;
饿汉式和懒汉式的区别:
饿汉式:加载类时比较慢(需要创建类的对象实例),但运行时获取类的对象比较快;另外,饿汉式是线程安全的(多个线程调用getInstance获取的是同一个对象);
懒汉式:加载类时比较快(不需要预先创建类的实例),但运行时获取类的对象比较慢;另外,懒汉式线程不安全(个人认为造成不安全的原因是在调用getInstance方法是才创建对象,如果多个线程在单例类未创建对象实例时同时调用getInstance方法,则可能创建了多个对象实例,实例的内部属性也会发生变化而导致不同);
综上,建议使用单例模式式使用饿汉式的,这样可以保证线程的安全,而加载类的速度的差别也不是很明显的;