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());
}
}