設(shè)計(jì)模式之單例模式
單例模式:
單例模式,顧名思義就是只有一個(gè)實(shí)例,并且她自己負(fù)責(zé)創(chuàng)建自己的對(duì)象,這個(gè)類(lèi)提供了一種訪問(wèn)其唯一的對(duì)象的方式,可以直接訪問(wèn),不需要實(shí)例化該類(lèi)的對(duì)象
單例模式,屬于創(chuàng)建類(lèi)型
實(shí)際代碼我放在了Github: https://github.com/liangtengyu/DesignPatterns-for-Java
應(yīng)用場(chǎng)景:
學(xué)習(xí)一個(gè)設(shè)計(jì)模式之前 我們先了解它的使用場(chǎng)景能夠幫我們更快的理解它,
單例模式只允許創(chuàng)建一個(gè)對(duì)象,因此更節(jié)省內(nèi)存,加快對(duì)象訪問(wèn)速度,因此對(duì)象需要被公用的場(chǎng)合適合使用,如多個(gè)模塊使用同一個(gè)數(shù)據(jù)源連接對(duì)象等等.如:
需要頻繁實(shí)例化然后銷(xiāo)毀的對(duì)象。 創(chuàng)建對(duì)象時(shí)耗時(shí)過(guò)多或者耗資源過(guò)多,但又經(jīng)常用到的對(duì)象。 有狀態(tài)的工具類(lèi)對(duì)象。 頻繁訪問(wèn)數(shù)據(jù)庫(kù)或文件的對(duì)象。
實(shí)現(xiàn)方式:
餓漢式
public class Singleton_3 {
//使用餓漢式 線程安全
private static Singleton_3 instance = new Singleton_3() ;
private Singleton_3() {
}
public static Singleton_3 getInstance() {
return instance;
}
}
懶漢式 - 線程安全
public class Singleton_2 {
//使用懶漢式 線程安全 不建議使用
private static Singleton_2 instance =null ;
private Singleton_2() {
}
public synchronized static Singleton_2 getInstance() {
if (instance !=null) return instance;
return new Singleton_2();
}
}
懶漢式 - 非線程安全
public class Singleton_1 {
//使用懶漢式 非線程安全
private static Singleton_1 instance =null ;
private Singleton_1() {
}
public static Singleton_1 getInstance() {
if (instance !=null) return instance;
return new Singleton_1();
}
}
靜態(tài)類(lèi)方式
public class sigleton0 { //使用靜態(tài)類(lèi)方式實(shí)現(xiàn)單例
private static ConcurrentHashMap cache = new ConcurrentHashMap();
}
內(nèi)部類(lèi)方式
public class Singleton_4 {
//使用內(nèi)部類(lèi)方式構(gòu)造單例, 線程安全并且懶加載
private AtomicInteger id = new AtomicInteger(0);
private Singleton_4() {
}
public static Singleton_4 getInstance(){
return SingletonCreator.singleton_4;
}
private static class SingletonCreator{
static Singleton_4 singleton_4 = new Singleton_4();
}
public Integer getIncrementId(){
return this.id.getAndIncrement();
}
雙重校驗(yàn)鎖方式
public class Singleton_5 {
//使用雙重鎖校驗(yàn) 線程安全
private static Singleton_5 instance =null ;
//滿足懶加載
private Singleton_5() {
}
public static Singleton_5 getInstance() {
if (instance !=null) return instance;
synchronized (Singleton_5.class) {
if (instance == null) {
return new Singleton_5();
}
}
return new Singleton_5();
}
}
原子類(lèi)方式
public class Singleton_6 {
//使用atomicrefence 使用CAS方式 支持懶加載
private static AtomicReference<Singleton_6> INSTANCE = new AtomicReference<Singleton_6>();
private Singleton_6() {
}
public static Singleton_6 getInstance(){
for (; ; ) {
Singleton_6 singleton_6 = INSTANCE.get();
if (null != singleton_6)return singleton_6;
INSTANCE.compareAndSet(null, new Singleton_6());
return INSTANCE.get();
}
}
實(shí)驗(yàn)
每次獲取單例對(duì)象的結(jié)果實(shí)際都是同一個(gè)對(duì)象
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
//獲取實(shí)例
Singleton_4 instance = Singleton_4.getInstance();
//輸出地址
System.out.println("實(shí)例的地址:" + instance);
//獲取id
System.out.println(instance.getIncrementId());
System.out.println("-------------------------------------------------");
}
}
結(jié)果 :
實(shí)例的地址:Singleton_4@63947c6b
0
-------------------------------------------------
實(shí)例的地址:Singleton_4@63947c6b
1
-------------------------------------------------
實(shí)例的地址:Singleton_4@63947c6b
2
-------------------------------------------------
實(shí)例的地址:Singleton_4@63947c6b
3
-------------------------------------------------
.....
這是設(shè)計(jì)模式的第一篇,后續(xù)會(huì)陸續(xù)更新.盡請(qǐng)期待,記得關(guān)注
評(píng)論
圖片
表情
