java在liunx下備份mysql資料,恢復資料
單例模式
一、簡介
定義:保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。
單例模式關鍵點:
- 建構函式私有
- 通過靜態方法或美劇返回單例物件
- 單例物件確保有且只有一個(尤其是多執行緒環境下)
- 確保單例物件在反序列化時不會重新構建物件
二、單例模式的實現
懶漢模式
public class SingletonPattern { private SingletonPattern() { } //懶漢模式 private static SingletonPattern singleton; public static SingletonPattern getSingleton() { if (singleton==null){ singleton=new SingletonPattern(); } return singleton; } }
該方式在類載入時就完成了初始化,所以它載入慢獲取快。
餓漢模式
public class SingletonPattern {
private SingletonPattern() {
}
//餓漢模式
private static SingletonPattern singletonPattern=new SingletonPattern();
public static SingletonPattern getSingletonPattern() {
return singletonPattern;
}
}
只有在第一次使用時才會初始化實現了懶載入,但是第一次使用時需要載入反應較慢
懶漢模式(執行緒安全)
public class SingletonPattern { private SingletonPattern() { } //懶漢模式(執行緒安全) private static SingletonPattern mSingleton; public static synchronized SingletonPattern getInstance() { if (mSingleton==null){ mSingleton=new SingletonPattern(); } return mSingleton; } }
相比普通懶漢模式增加了synchronized關鍵字以保證執行緒安全,但是每次呼叫時都需要進行同步,造成不必要的同步開銷,而且大部分時候我們是用不到同步的
雙重檢查模式
public class SingletonPattern {
private SingletonPattern() {
}
//雙重檢查模式
private volatile static SingletonPattern instance;
public static SingletonPattern getinstance() {
if (instance==null){
synchronized (SingletonPattern.class){
if (instance==null){
instance=new SingletonPattern();
}
}
}
return instance;
}
}
既可以在需要的時候才初始化又能保證執行緒安全,可以看出使用了兩層判空,第一層是為了避免不必要的同步,第二層則是為了在null的情況下建立例項。在高併發環境下也有一定的缺陷,雖然發生的概率很小。DCL雖然在一定程度解決了資源的消耗和多餘的同步,執行緒安全等問題,但是他還是在某些情況會出現失效的問題。還有這裡的volatile是保證原子性可見性
靜態內部類單例模式
public class SingletonPattern {
private SingletonPattern() {
}
//靜態內部類模式
private static class Instance{
private static final SingletonPattern singletonPattern=new SingletonPattern();
}
public static SingletonPattern getmSingleton() {
return Instance.singletonPattern;
}
}
第一次載入SingletonPattern類時並不會初始化singletonPattern,只有第一次呼叫getmSingleton方法時虛擬機器載入Instance並初始化singletonPattern,這樣不僅能確保執行緒安全也能保證SingletonPattern類的唯一性,所以推薦使用靜態內部類單例模式。
列舉單例
//列舉模式
public enum Singleton {
INSTANCE;
public void doSomeThing() {
}
}
預設列舉例項的建立是執行緒安全的,並且在任何情況下都是單例,上述講的幾種單例模式實現中,有一種情況下他們會重新建立物件,那就是反序列化,將一個單例例項物件寫到磁碟再讀回來,從而獲得了一個例項。反序列化操作提供了readResolve方法,這個方法可以讓開發人員控制物件的反序列化。在上述的幾個方法示例中如果要杜絕單例物件被反序列化是重新生成物件,就必須加入如下方法:
`private Object readResolve() throws ObjectStreamException{ return singleton; }`
即返回已存在的例項而不是建立新的
使用容器實現單例模式
//使用容器實現單例
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String, Object>();
private Singleton() {
}
public static void registerService(String key, Object instance) {
if (!objMap.containsKey(key)) {
objMap.put(key, instance);
}
}
public static Object getService(String key) {
return objMap.get(key);
}
}
用SingletonManager 將多種的單例類統一管理,在使用時根據key獲取物件對應型別的物件。這種方式使得我們可以管理多種型別的單例,並且在使用時可以通過統一的介面進行獲取操作,降低了使用者的使用成本,也對使用者隱藏了具體實現,降低了耦合度
參考《Android原始碼設計模式解析與實戰》