單例模式(singleton pattern
):確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項,這個類稱為單例類,它提供全域性訪問的方法。單例模式是一種物件建立型模式。
單例模式有三個要點:一是某個類只能有乙個例項;二是它必須自行建立這個例項;三是它必須自行向整個系統提供這個例項。
準備在**中新增乙個訪問計數器,為了保證計數器在程式中唯一,現在需要將計數器設計為單例模式,否則可能出現多個計數器導致計數不正確。
示例:
public
void
test()
throws interruptedexception
thread.
sleep
(100l)
; system.out.
println
get())
;}
public
class
public integer get()
public()
}
public
class
public integer get()
public
static()
}}
問題得到解決,但是每次獲取物件的時候都會加鎖,在高併發場景下可能導致效能大大降低,但可以通過減小鎖的粒度來優化,因為我們並不需要對整個方法加鎖,只需要對if
判斷加鎖即可:
public()
}}
問題貌似得到解決,但其實不然,因為可能同時有多個執行緒進入了if塊,那麼會有多個執行緒先後進入同步塊,還是會出現初始化多次的情況,那我們可以在同步塊內再做一次判斷,這樣在同步塊前做一次判斷,進入同步塊後再做一次判斷的方式稱為「雙重檢查鎖定(double-check locking
)」:
private
volatile..
.public()}}}
記得用volatile
修飾單例物件,可以確保執行緒之間的可見性和禁止指令重排,一旦物件被初始化,其他執行緒會立馬拿到更新後的值去和null比較,從而防止執行緒用本地副本和null比較,也就不會導致例項被多次初始化。但這種解決方法不是特別優雅,volatile
也會一定程度上降低效能,所以雙重檢查鎖定也不是乙個完美的解決方法。
有沒有結合懶載入和按需載入兩種方式的方法呢?是有的:
public
class
public integer increase()
public integer get()
public
static()
}
設計模式 二 單例模式
建立乙個物件並不難,但當我們不得不為每新新增一種抽象類或介面而到處修改客戶 時,就不得不思考直接使用new建立物件帶來的高耦合。建立型別的模式將使用物件和 例項化物件 進行了分離。建立型別模式包括 單例模式 工廠方法模式 原型模式。下面先看單例模式 單例模式 保證乙個類在系統裡只有乙個例項化物件。應...
設計模式(二) 單例模式
單例模式 用來建立只能有乙個例項的物件。確保乙個類只有乙個例項,並提供乙個全域性訪問點。有的時候我們不希望乙個類被建立出多個物件,因為多個例項會帶來許多不好的影響。經典單例模式 public class singleinstance public static singleinstance geti...
設計模式(二)單例模式
單例模式 保證只有乙個物件,每次獲取物件獲取到的都是同乙個物件。單例模式是我們程式中最常見的設計模式,很多任務具類都設計成單例模式,spring中的bean也有單例,單他不是真正的單例。單例模式總結下來有幾種寫法,他們共性就是私有的構造方法。package com.designpattern.sin...