單例模式的五種建立方式 涉及原理

2021-10-07 01:55:59 字數 2072 閱讀 7912

使用靜態內部類

public

class

singleton2

public

static singleton2 getinstance()

}

/**

* 單例模式:確保乙個類只有乙個例項,並提供乙個全域性訪問點

* 管理共享的資源如:執行緒池,登錄檔設定,資料庫連線池

* 如果使用多個類載入器,會導致單例失效而產生多個例項

* 解決方案:自行指定類載入器,並指向同乙個類載入器

* 全域性變數缺點

* 不能確保只有乙個例項

* 變數過多導致命名空間汙染

* @author administrator

* */

public

class

singleton

public

static singleton getinstance()

}

/**

* 多執行緒解決方案1

* 缺點:只有第一次執行方法時才需要同步,設定好uniqueinstance變數,不再需要sync了,之後每次呼叫都浪費資源

* * @author administrator

* */

public

class

singleton1

public

static

synchronized singleton1 getinstance()

}

這裡引入乙個雙重檢查加鎖的概念

new singleton3()並不是乙個原子操作

// 建立 cache 物件例項,分配記憶體

// 複製棧頂位址,並再將其壓入棧頂

3: dup

// 呼叫構造器方法,初始化 cache 物件

4: invokespecial #6

// method "":()v

// 存入區域性方法變數表

假設當執行到第三步,另乙個執行緒執行getinstance()獲取物件,獲取的會是乙個尚未初始化完成的物件.

/**

* 多執行緒解決方案3:雙重檢查加鎖

* * @author administrator

* */

public

class

singleton3

public

static singleton3 getinstance()

}return uniqueinstance;

}}

首先static的在類載入階段只會載入一次,這就保證了之後每次使用單例物件不需要重複載入的問題.

第二當執行static的時候會執行clinit()方法給靜態物件賦值,當多個執行緒搶占的時候,會有加鎖操作,只會有乙個執行緒成功執行clinit()方法,且執行成功後,後續的執行緒不會再執行clinit()方法,這就保證了clinit()只會執行一次,也就是說static修飾的物件只會new一次.

也就解決了上述單例物件建立需要每次判斷是否為null以及重複加鎖的問題了.

/**

當第一次訪問類中的靜態欄位時,會觸發類載入,並且

同乙個類只載入一次。靜態內部類也是如此,類載入過程由類載入器負責加鎖,從而保證執行緒

安全。* @author administrator

* */

public

class

singleton4

private

singleton4()

public

static singleton4 newinstance (

)}

單例模式的五種方式

核心作用 保證乙個類只有乙個例項,並且提供了乙個訪問該例項的全域性訪問點。常見應用場景 單例模式的優點 常見的五種單例模式 主要其他 延遲載入 lazy load 也稱為懶載入。簡單來說,就是只有在使用的時候,才去呼叫或載入。是延遲載入。實現 懶漢式 單例模式 public class single...

單例模式的五種實現方式

1.最容易想到的方式 public class singleton public static singleton getinstance public static void main string args 優點是 簡單 缺點是 無論用沒用到instsnce,都會進行初始化。2.延遲載入 laz...

單例模式的五種實現方式

單例模式 無論在什麼時候,該類只有乙個例項。實現單例模式的要點就是提供乙個私有的無參建構函式。一 餓漢單例模式public class singleobject public static singleobject getinstance 二 懶漢單例模式 懶漢的意思就是慢悠悠的,不著急,也就是在呼...