1. 概述
來(lái)開(kāi)新坑啦!(你為啥總開(kāi)坑不填)哈误,這次來(lái)鞏固下學(xué)習(xí)的設(shè)計(jì)模式相關(guān)的內(nèi)容蔓姚,如果內(nèi)容有誤或者有好的建議的請(qǐng)大家請(qǐng)?jiān)谠u(píng)論區(qū)留言。
2. 單例模式
首先來(lái)介紹一下設(shè)計(jì)模式中最簡(jiǎn)單的單例模式
2.1單例模式的意義
那么什么是單例模式呢幸海?從字面意思來(lái)理解即可祟身,就是一個(gè)類(lèi)最多只有一個(gè)實(shí)例(對(duì)象),并且它提供了一個(gè)全局訪(fǎng)問(wèn)點(diǎn)物独。原理很簡(jiǎn)單袜硫,那么它一般用在什么地方呢?比如:
(1)正如其描述的一樣挡篓,在系統(tǒng)資源中只有一個(gè)的東西我們可以用單例模式來(lái)描述它婉陷,線(xiàn)程池、緩存和硬件設(shè)備等等.
(2)多個(gè)實(shí)例會(huì)造成沖突官研,結(jié)果不一致的情況下可以使用單例模式
2.2單例模式的類(lèi)圖結(jié)構(gòu)
Singleton |
---|
static uniqueInstance |
private Singleton(), static getInstance() |
來(lái)說(shuō)明一下秽澳,這個(gè)Singleton代表類(lèi)名,他有一個(gè)私有的靜態(tài)實(shí)例的引用戏羽,它的構(gòu)造函數(shù)是私有的担神,它還有一個(gè)獲取內(nèi)部實(shí)例的公有靜態(tài)方法。
(1)靜態(tài)實(shí)例是為了保證全局性始花,私有修飾符是為了保證外部不會(huì)對(duì)唯一實(shí)例進(jìn)行修改
(2)私有的構(gòu)造函數(shù)是為了不讓外部new新的實(shí)例對(duì)象
(3)公有的獲取實(shí)例方法是為了給外部提供一個(gè)獲取唯一實(shí)例的窗口妄讯。
2.3 兩種方式與簡(jiǎn)單代碼實(shí)現(xiàn)
在寫(xiě)代碼之前還要說(shuō)明一下單例模式的兩種方式孩锡,根據(jù)實(shí)例化時(shí)機(jī)的不同可以分為餓漢模式和懶漢模式。
(1)所謂餓漢模式亥贸,即在單例類(lèi)被加載時(shí)即會(huì)實(shí)例化一個(gè)對(duì)象交給自己的引用躬窜。來(lái)直看看代碼吧:
public class Singleton{
// 唯一實(shí)例
private static Singleton singletonInstance = new Singleton();
// 私有構(gòu)造函數(shù)
private Singleton(){}
// 獲取實(shí)例的方法
public static Singleton getSingletonInstance() {
return singletonInstance;
}
// 類(lèi)的 其他方法
}
(2)懶漢模式則是在調(diào)用獲取實(shí)例方法之后才會(huì)生成實(shí)例,來(lái)看下代碼:在里面有一點(diǎn)需要十分注意炕置,那就是getSingletonInstance方法的同步鎖修飾符荣挨,這是為了防止在多線(xiàn)程調(diào)用同一事物中產(chǎn)生多個(gè)實(shí)例的手段,但是這樣會(huì)有一個(gè)問(wèn)題讹俊,就是系統(tǒng)資源消耗會(huì)有所增加垦沉。所以一般Java中多使用餓漢模式。
public class Singleton2{
// 唯一實(shí)例
private static Singleton2 singletonInstance;
// 私有構(gòu)造函數(shù)
private Singleton2(){}
// 獲取實(shí)例的方法
public static synchronized Singleton2 getSingletonInstance() {
if(singletonInstance == null)
{
singletonInstance = new Singleton2();
}
return singletonInstance;
}
// 類(lèi)的 其他方法
}
但是也是可以?xún)?yōu)化一下的仍劈,如下代碼:這種辦法叫做雙重檢查加鎖法厕倍,因?yàn)檫M(jìn)入同步區(qū)域后,只會(huì)有一個(gè)線(xiàn)程進(jìn)入這個(gè)區(qū)域贩疙,而且之后不會(huì)進(jìn)入同步區(qū)域讹弯,所以消耗會(huì)比上一種方法要好。
/**
*
*懶漢模式優(yōu)化
*
* */
class Singleton3{
// 唯一實(shí)例
private volatile static Singleton3 singletonInstance;
// 私有構(gòu)造函數(shù)
private Singleton3(){}
// 獲取實(shí)例的方法
public static synchronized Singleton3 getSingletonInstance() {
if(singletonInstance == null)
{
synchronized (Singleton3.class)
{
if(singletonInstance == null)
{
singletonInstance = new Singleton3();
}
}
}
return singletonInstance;
}
// 類(lèi)的 其他方法
}
2.4單例模式的優(yōu)點(diǎn)
(1)內(nèi)存中只有一個(gè)對(duì)象这溅,節(jié)省內(nèi)存空間
(2)避免頻繁的創(chuàng)建銷(xiāo)毀對(duì)象组民,提高性能
(3)避免對(duì)共享資源的多重占用
(4)可以全局訪(fǎng)問(wèn)
2.5單例模式的使用場(chǎng)景
(1)需要頻繁實(shí)例化然后銷(xiāo)毀實(shí)例的對(duì)象
(2)有狀態(tài)的工具類(lèi)對(duì)象
(3)創(chuàng)建復(fù)雜且消耗資源的對(duì)象
(4)頻繁訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)或者文件的對(duì)象
2.6注意事項(xiàng)
(1)只能使用單例類(lèi)提供的方法來(lái)實(shí)例化對(duì)象,不可以使用反射悲靴,不然會(huì)產(chǎn)生新的實(shí)例
(2)不要斷開(kāi)單例類(lèi)對(duì)象和單例類(lèi)靜態(tài)引用的操作