單例類例項化出來的物件是堆裡的乙個物件,且是同乙個物件使用場景:
當物件需要頻繁的建立和銷毀的時候,單例可以提高效能優點:
.只有乙個例項物件,可以節省很多空間。
.物件不會被重複的 new ,降低了對系統資源的重複占用,提高了效能。
缺點:
.只有乙個物件的話,無疑擴充套件性差了很多。(想擴充套件你就得來改這個 單例類)
.場景比較多的時候,單例就顯得很無力了,根本無法應對,這時候還是不要使用單例了
.配合連線池時,不推薦使用,單例又不會死,一直來,池子就滿了。
/**
* @classname hungary 餓漢式單例
* @description 最基本的單例模式
* @author skysong
* @date 2020-09-15 22:09
*/public
class
hungary
//先把物件 new 出來
/** * 一上來就建立物件的話 容易造成浪費空間的問題
* class 被載入時 new 就分配了空間,但我們不一定用
* 這也奠定了 懶漢式 橫空出世 的必要性
*/public
final
static hungary hungary =
newhungary()
;public
static hungary getinstance()
}
基本實現:
/**
* @classname lazyman 懶漢式 單例
* @description
* @author skysong
* @date 2020-09-15 22:24
*/public
class
lazyman
//先不例項化物件
public
static lazyman lazyman;
//當呼叫時,再建立
public
static lazyman getinstance()
return lazyman;
}}
分析問題:
如果系統是單執行緒執行的話,這個寫法沒有問題。 但多執行緒就會出現問題……我們用 10 個執行緒併發 測試一下
public
class
lazyman
public
static lazyman lazyman;
public
static lazyman getinstance()
return lazyman;
}public
static
void
main
(string[
] args)}.
start()
;}}}
結果不一,甚至出現多個 例項
thread-1這時需要引出我們的 dcl懶漢式thread-2
thread-0
process finished with exit code 0
/**
* @classname lazyman dcl懶漢式 單例
* @description 加入鎖,解決多執行緒併發 單例變多例 問題
* @author skysong
* @date 2020-09-15 22:24
*/public
class
lazyman
public
static lazyman lazyman;
//dcl懶漢式(雙重檢測,一層加鎖)
public
static lazyman getinstance()
}}return lazyman;
}public
static
void
main
(string[
] args)}.
start()
;}}}
分析問題:
new 物件的過程 不是乙個原子性操作!當發生指令重排的時候,會出現問題:過程如下:
1.分配空間
2.初始化(執行構造方法)
3.讓 引用 指向這個空間
我們希望的執行順序時 1->2->3此時,引用已經指向了空間(lazyman 在這一時刻後就不在是 null 了),但這個空間還沒有完成初始化但 cpu 為了提高效率,有可能會 執行為 1->3->2
為了解決這個問題,剛才的**需要改進:(給這個物件加上volatile ,防止它指令重排 )
package single;
/** * @classname lazyman 懶漢式 單例
* @description
* @author skysong
* @date 2020-09-15 22:24
*/public
class
lazyman
public
volatile
static lazyman lazyman;
//dcl懶漢式(雙重檢測,一層加鎖)
public
static lazyman getinstance()
}}return lazyman;
}public
static
void
main
(string[
] args)}.
start()
;}}}
在內部類裡呼叫,這樣別人再怎麼呼叫外部類都不會影響到單例。
/**
* @classname outer
* @description
* @author skysong
* @date 2020-09-15 23:53
*/public
class
outer
public
static outer getinstance()
public
static
class
inner
}
設計模式 單例模式詳解
1.懶漢式,執行緒不安全 public class singletonpattern 懶漢式,執行緒不安全 private static singletonpattern instance public static singletonpattern getinstance return insta...
設計模式 單例模式詳解
單例模式 singleton 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。通常我們可以讓乙個全域性變數使得乙個物件被訪問,但它不能防止你例項化多個物件。乙個最好的辦法就是,讓類自身負責儲存它的唯一例項。這個類可以保證沒有其他例項可以被建立,並且它可以提供乙個訪問該例項的方法。我們知道,o...
單例設計模式(詳解)
模式 模式就是解決一類問題的固定步驟 單例設計模式 保證乙個類在記憶體中只有乙個物件 舉例 多個瀏覽器向伺服器傳送請求,只建立乙個servlet物件處理相應的請求,而不是每接收乙個請求,就建立乙個servlet物件 1.餓漢單例設計模式 1.私有化建構函式 2.宣告本類的引用型別變數,並且使用該變數...