學習筆記-設計模式入門基礎篇-單例模式
餓漢式:
在使用之前就先 new 出來再說,避免了線程安全問題
public class Hungry {
private Hungry(){}
private final static Hungry hungry = new Hungry();
public static Hungry getInstance(){
System.out.println(System.currentTimeMillis()+":"+ hungry);
return hungry;
}
}
懶漢式
默認加載的時候不實例化,在需要使用的時候才實例化
1、線程不安全
public class LazyOne {
private LazyOne (){}
private static LazyOne lazyOne = null;
public static LazyOne getInstance(){
if (lazyOne== null){
lazyOne = new LazyOne();
}
return lazyOne;
}
}
2、線程安全,但是效率慢
public class LazyTwo {
private LazyTwo(){}
private static LazyTwo lazyTwo = null;
public static synchronized LazyTwo getInstance(){
if (lazyTwo== null){
lazyTwo = new LazyTwo();
}
return lazyTwo;
}
}
3、線程安全速度快
public class LazyThree {
public static final LazyThree getInstance(){
return LazyHolder.LAZY;
}
private static class LazyHolder {
private static final LazyThree LAZY = new LazyThree();
}
}
註冊登記式單利
每使用一次就往固定的容器中去註冊,並且將使用過的對象進行緩存,下次去使用對象的時候直接去緩存中取,以保證每次獲取的都是同一個對象
/**
* 註冊登記式單利
*/
public class RegisterMap {
private RegisterMap (){}
private static Map<String,Object> register = new HashMap<>();
private static RegisterMap getInstance(String name){
if (name==null){
name= RegisterMap.class.getName();
}
if(register.get(name)==null ){
register.put(name,new RegisterMap());
}
return (RegisterMap)register.get(name);
}
}
序列化與反序列化保證單利:
重寫readResolve 方法
public class Seriable implements Serializable {
private final static Seriable INSTANCE = new Seriable();
private Seriable(){}
public static Seriable getInstance (){
return INSTANCE;
}
/**
* 實現序列化與反序列化中,對象的重複利用,由JVM 自動調用
*
* @return
*/
private Object readResolve(){
return INSTANCE;
}
}