单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
一、懒汉式单例
懒汉式单例在类被加载的时候,唯一实例已经被创建。这个设计模式在Java中容易实现,在别的语言中难以实现
package cn.id5.singleton;
public class LazySingleton {
/*** 私有静态对象,加载时候不做初始化 */
private static LazySingleton myIntance = null;
/*** 私有构造方法,避免外部创建实例 */
private LazySingleton(){}
/*** 静态工厂方法,返回此类的唯一实例.* 当发现实例没有初始化的时候,才初始化. * @return LazySingleton */
synchronized public static LazySingleton getIntance(){
if(myIntance==null){
myIntance = new LazySingleton();
}
return myIntance;
}
public static void main(String[] args) {
LazySingleton lazySingleton = LazySingleton.getIntance();
LazySingleton lazySingleton1 = LazySingleton.getIntance();
if(lazySingleton==lazySingleton1){
System.out.println("同一个实例");
}else System.out.println("不是同一个实例");
} }
二、饿汉式单例
饿汉式单例在类加载的时候不创建单例实例。只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例
package cn.id5.singleton;
public class EgerSingleton {
/**私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象*/
private static final EgerSingleton myInstance = new EgerSingleton();
/*** 私有构造方法,避免外部创建实例*/
private EgerSingleton(){}
/*** 静态工厂方法,返回此类的唯一实例.* @return EagerSingleton */
public static EgerSingleton getInstance(){
return myInstance;
}
public static void main(String[] args) {
EgerSingleton eagerSingleton = EgerSingleton.getInstance();
EgerSingleton eagerSingleton1 = EgerSingleton.getInstance();
if(eagerSingleton==eagerSingleton1){
System.out.println("同一个实例");
}else System.out.println("不是同一个实例");
}
}
三、登记式单例
登记式单例这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。
package cn.id5.singleton;
import java.util.HashMap;
import java.util.Map;
public class RegSingleton {
/*** 登记薄,用来存放所有登记的实例*/
private static Map <String , RegSingleton> m_registry = new HashMap();
//在类加载的时候添加一个实例到登记薄
static {
RegSingleton rs = new RegSingleton();
m_registry.put(rs.getClass().getName(), rs);
}
/*** 受保护的默认构造方法*/
protected RegSingleton(){}
/*** 静态工厂方法,返回指定登记对象的唯一实例;
* 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回
* @param name
* @return
RegSingleton */
public static RegSingleton getIntance(String name){
if(name == null){
name="RegSingleton";
}
if(m_registry.get(name)==null){
try {
m_registry.put(name, (RegSingleton)Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return m_registry.get(name);
}
public static void main(String[] args) {
RegSingleton re = new RegSingleton();
RegSingleton re1= new RegSingleton();
if(re == re1){
System.out.println("同一个实例");
}
else System.out.println("不是同一个实例 ");
}
}