java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。
例如:log4j日志就是一个典型的单例、spring bean创建的默认单例模式
一、懒汉式单例
package com.design.singleton;
/**
* 懒汉式单例--在第一次调用的时候实例化
* @author
*
*/
public class LazySingleton {
/**
* 构造私有,以免外部构造
*/
private LazySingleton(){
}
//创建实例
private static LazySingleton INSTANCE = null;
/**
* 外部访问实例
* @return
*/
public synchronized static LazySingleton getInstance(){
if(INSTANCE == null)
INSTANCE = new LazySingleton();
return INSTANCE;
}
}
二、饿汉式单例
package com.design.singleton;
/**
* 饿汉式--在类加载的时候创建实例
* @author
*
*/
public class HungerSingleton {
/**
* 不能被外部实例化
*/
private HungerSingleton(){
}
//创建一个实例
private static HungerSingleton INSTANCE = new HungerSingleton();
/**
* 调用这个实例化
* @return
*/
public static HungerSingleton getInstance(){
return INSTANCE;
}
}
三、登记式单例
package com.design.singleton;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* 登记式单例
* @author
*
*/
public class SingletonFactory {
//存放单例实例
private static ConcurrentMap<String, Object> managedSingletons = new ConcurrentHashMap<String, Object>();
/**
* 根据类名(需加上包路劲)获取对应实例,若不存在则创建
* @param className
* @return
*/
public static Object getInstance(String className){
if(!managedSingletons.containsKey(className)){
createInstance(className);
}
return managedSingletons.get(className);
}
/**
* 获取实例,若没有这个实例则创建
* @param c
* @return
*/
public static Object getInstance(Class<?> c){
return getInstance(c.getName());
}
/**
* 创建一个实例
* @param className
*/
public static void createInstance(String className){
synchronized(managedSingletons){
try {
managedSingletons.put(className, Class.forName(className).newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 创建一个实例
* @param c
*/
public static void createInstance(Class<?> c){
createInstance(c.getName());
}
/**
* 移除实例
* @param className 类名称加路劲
*/
public static void removeInstance(String className){
if(!managedSingletons.containsKey(className)){
synchronized(managedSingletons){
managedSingletons.remove(className);
}
}
}
/**
* 移除实例
* @param c
*/
public static void removeInstance(Class<?> c){
removeInstance(c.getName());
}
}