天天看點

單例模式和靜态類單例模式靜态類單例和靜态類的差別

單例模式

這是設計模式中最簡單的模式,通過這種模式,可以使一個程序中,隻有一個執行個體。是以這種執行個體的建立不是 new 出來的。

看一個java庫中的單例, Runtime提供了私有的構造函數,這樣,在外部就沒有辦法通過構造函數直接建立,然後在内部進行了執行個體化,通過一個公共的靜态方法,将内部執行個體暴露出來,這樣就限制了這個類的執行個體是全局唯一的,外部隻能通過暴露出來的getRuntime方法進行執行個體化。

單例模式和靜态類單例模式靜态類單例和靜态類的差別
全局唯一執行個體,就使得記憶體開銷減少,也減少了頻繁建立的銷毀的過程。在資料庫或者其他I/O的情景下也減少了記憶體的開銷。

上圖中的單例又屬于單例中的 餓漢模式,在類加載的時候,就進行了初始化。将上面的代碼改造下,

單例模式和靜态類單例模式靜态類單例和靜态類的差別

這樣類并不是在加載的時候進行執行個體化,而是在調用的時候才進行了執行個體化,這種方式是懶漢模式 ,實作了類的懶加載,但是如果多線程同時對這個類進行調用,那就會多次進行執行個體化,顯然就不是單例模式了。

這時候可以對執行個體化的方法加鎖。

單例模式和靜态類單例模式靜态類單例和靜态類的差別

但是加鎖會對應能有一定的影響,使用雙重檢查在多線程的情況下回有改善,這種是雙重鎖 ,

單例模式和靜态類單例模式靜态類單例和靜态類的差別
要真正的實作懶加載,還是需要ClassLoad模式,如果沒有特殊需求,使用單例模式,使用第一種方式,在加載的時候進行執行個體化,可以更簡單,也少了很多沖突

靜态類

這個更比較常見一點,通常用在工具類裡面,直接通過  類名.方法名  進行調用。

靜态類和單例模式都是不需要在調用前進行執行個體化,那他們之間有什麼差別呢?

單例和靜态類的差別

1. 在靜态類中不适合維護任何變量,因為他可以被任意的更改。如果僅僅是需要一個對象提供各種靜态方法,那很明顯靜态類更适合。如果需要對某些資訊進行維護,那麼可以使用單例,外部不能對裡面的資訊進行随便修改。

2. 靜态類的方法不能被重寫,而可以對靜态類中的方法進行重寫。

3. 加載時間不同,靜态類在首次加載時被執行個體化,而單例可以懶加載或者異步加載, 在spring中,也應用了大量的單例模式。