1.單例設計模式(懶漢式,餓漢式,列舉式,雙重檢測鎖式,靜態內部類式)
設計模式分類:
1:建立型模式:
單例模式,工廠模式,抽象工廠模式,建造者模式,原型模式;
2:結構型模式:
介面卡模式,橋接模式,裝飾模式,組合模式,外觀模式,享元模式,代理模式
3:行為型模式:
模板方法模式,命令模式,迭代器模式,觀察者模式,中介者模式,備忘錄模式,
直譯器模式,狀態模式,策略模式,職責鏈模式,訪問者模式。
單例模式應用場景:
windows的task manager(工作管理員)就是很典型的單例模式,
windows的recycle bin(回收站)也是典型的單例應用,在整個系統執行過程中,回收站一直
維護僅有的一個例項。
專案中,讀取配置檔案的類,一般也只有一個物件,沒有必要每次使用配置檔案資料,每次
new一個物件去讀取,
應用程式的日誌應用,一般都可用單例模式實現,這一般是由於共享的日誌檔案一直處於開啟狀態,因為
只能有一個例項去操作,否則內容不好追加。
資料庫連線池的設計一般也是採用單例模式,因為資料庫連線是一種資料庫資源
作業系統的檔案系統,也是大的單例模式實現的具體例子,一個作業系統只能有一個檔案系統
Application也是單例的典型應用(servlet程式設計中會涉及到)
在spring中,每個bean預設就是單例的,這樣做的優點是spring容器可以管理
在servlet程式設計中,每個servlet也是單例
在spring mvc框架/struts1框架中,控制器物件也是單例
單例模式的實現(5種)
常用:
餓漢式(執行緒安全,呼叫效率高,但是不能延時載入)
懶漢式(執行緒安全,呼叫效率不高,可以延時載入)
其他:
雙重檢測鎖式(由於jvm底層內部模型原因,偶爾會出問題,不建立使用)
靜態內部類式(執行緒安全,呼叫效率高,但是可以延時載入)
列舉單例(執行緒安全,呼叫效率高,不能延時載入)
常用惡漢式,懶漢式:
/** * 測試惡漢式單例模式 * @author Administrator * */ public class SingleTonDemo1 { //類初始化時,立即載入物件。天然的執行緒安全的 private static SingleTonDemo1 instance = new SingleTonDemo1(); //類初始化時,立即載入 private SingleTonDemo1() { } //方法沒有同步,呼叫效率高 public static SingleTonDemo1 getInstance() { return instance; } }
/** * 測試懶漢式單例模式 * @author Administrator * */ public class SingleTonDemo2 { private static SingleTonDemo2 instance = null; private SingleTonDemo2() { } //方法使用同步,呼叫效率低 public static synchronized SingleTonDemo2 getInstance() { if(instance == null) { instance = new SingleTonDemo2(); } return instance; } }
/**
* 列舉單例模式
* @author Administrator
*
*/
public enum SingleTonDemo4 {
INSTANCE; //雖然只有一行
}
public class TestEnum {
//測試列舉單例
public static void main(String[] args) {
SingleTonDemo4 instance1 = SingleTonDemo4.INSTANCE;
SingleTonDemo4 instance2 = SingleTonDemo4.INSTANCE;
SingleTonDemo4 instance3 = SingleTonDemo4.INSTANCE;
System.out.println(instance1 == instance3);
}
}
/**
* 靜態內部類式單例設計模式
* @author Administrator
*
*/
public class SingleTonDemo3 {
//只會被載入一次,執行緒安全
static class Nested {
private static SingleTonDemo3 instance = new SingleTonDemo3();
}
private SingleTonDemo3() {
}
public static SingleTonDemo3 getInstance() {
return Nested.instance;
}
}
<p>/**
* 雙重檢測鎖式單例設計模式
* @author Administrator
*
*/
public class SingleTonDemo5 {</p><p> private static volatile SingleTonDemo5 instance;
private SingleTonDemo5() {
}
//getInstance()方法檢查了兩次來判斷INSTANCE是否為null,這就是為什麼叫雙檢索的原因,
//記住雙檢索在java5之前是有問題的,但是java5在記憶體模型中有了volatile變數之後就沒問題了
public static SingleTonDemo5 getInstance(){
if(instance == null){
synchronized(SingleTonDemo5.class){
if(instance == null){
instance = new SingleTonDemo5();
}
}
}
return instance;
}
}</p>