單例模式的寫法,和DCL

2021-10-05 18:26:58 字數 3250 閱讀 6586

總結設計模式是在大量的實踐中總結和理論化之後優的**結構、程式設計風格、以及解決問題的思考方式。

所謂類的單例設計模式,就是採取一定的方法保證在整個的軟體系統中,對某個類只能存在乙個物件例項。

單列有如下幾個特點:

class

singleton

//2.內部建立類的物件

//4.要求此物件也必須宣告為靜態的

private

static

singleton instance =

newsingleton()

;//3.提供公共的靜態的方法,返回類的物件

public

static

singleton

getinstance()

}

這裡的寫法是執行緒不安全的

class

singleton

//2.宣告當前類物件,沒初始化

//4.此物件也必須宣告為static的

private

static

singleton instance =

null

;//3.宣告public、static的返回當前類物件的方法

public

static

order

getinstance()

return instance;

}}

public

class

singleton

public

synchronized

static

singleton

getinstance()

return instance ;

}}

public

class

singleton

public

static

singleton

getinstance()

}return instance ;

}}

將synchronized關鍵字加在內部,也就是說當呼叫的時候是不需要加鎖的,只有當instance為null,並建立物件的時候才需要加鎖,效能上有了一定的提公升。

但是這樣就沒有問題了嗎?

上面的類的getinstance函式的位元組碼檔案為:

0 getstatic #2

泛型/singleton

.instance>

3 ifnonnull 37(+

34)6 ldc #3

泛型/singleton

>

8 dup

9 astore_0

10 monitorenter

11 getstatic #2

泛型/singleton

.instance>

14 ifnonnull 27(+

13)17new #3

泛型/singleton

>

20 dup

21 invokespecial #4

泛型/singleton

.>

24 putstatic #2

泛型/singleton

.instance>

27 aload_0

28 monitorexit

29goto37(

+8)32 astore_1

33 aload_0

34 monitorexit

35 aload_1

36 athrow

37 getstatic #2

泛型/singleton

.instance>

40 areturn

其中的instance =new singleton(); 被分解為了

//首先在堆上面申請一塊記憶體,這個時候物件裡面的屬性複製為初始值

17new #3

泛型/singleton

>

20 dup

//呼叫建構函式,給成員變了賦值

21 invokespecial #4

泛型/singleton

.>

//把引用賦值給instance

24 putstatic #2

泛型/singleton

上圖中可以看出執行緒2 拿到了沒有初始化的物件。如果沒有看懂,看下圖

}}

通過加上volatile修飾變數,能夠防止指令重排序

volatile的作用

但是這個volatile關鍵字可能會使得jvm減少對**的優化,所以執行效率不高

靜態內部類的優點是:外部類載入時並不需要立即載入內部類,內部類不被載入就不去初始化物件,故而不會占用記憶體。只有當呼叫getinstance()方法第一次被呼叫時,才會去初始化instance,第一次呼叫getinstance()方法會導致虛擬機器載入內部類,這種方法不僅能確保執行緒安全,也能確保單列的唯一性.

public

class

singleton

public

static

class

singletonpro

public

static

singleton

getinstance()

}

使用列舉類不僅可以解決執行緒同步,還可以防止反序列化。

public

enum

singleton

使用列舉來實現單例項控制會更加簡潔,而且jvm從根本上提供保障,絕對防止多次例項化,是更簡潔、高效、安全的實現單例的方式。

個人覺得最好寫的就是靜態內部類了,同時效率也高。

dcl單例模式

有時候我們需要對外呈現只有乙個物件,簡單來說就是講物件私有化,像資料那樣,只能通過get方法得到。這裡使用doublechecking來進行該操作,即在get方法裡面加入兩個判斷該物件是否為空,同時為了避免指令重排導致執行緒獲得空物件,加入volatile,而且私有化構造器。public class...

DCL單例模式

單例模式 外部不能new物件,類的內部有且只有乙個物件,僅僅用乙個靜態方法與外界進行互動。public class doublecheckedlocking 外部只能通過這個get方法和此物件進行交流 public static doublecheckedlocking getinstance 繫結...

單例模式的DCL問題

剛剛寫完靜態 塊問題,突然想到之前單例模式的坑,雖然解決辦法知道了,但是之前的原理不太明白,剛剛突然想清楚了。感謝大神 餓漢式 class single 私有化建構函式。private static single s new single 建立私有並靜態的本類物件。public static sin...