Java設計模式 單例模式

2021-07-13 08:58:49 字數 1686 閱讀 2513

單例模式是一種大家比較熟悉的模式,就不多做介紹了。下面說一下多執行緒中遇到的問題吧

比如有乙個計數器,每次輸出都會自增1,常規單例模式的寫法如下:

public

class counter

public

static counter getinstance()

system.out.println("sum:"+sum++);

return counter;

}}

建立100個執行緒輸出sum,測試**如下:

public

class test

}).start();

} }}

我們來看一下單例模式的定義:確保乙個類只有乙個例項,並提供乙個全域性訪問點。

根據這個定義來看,輸出的結果應該為按順序為0到99,但是實際輸出如下:

sum:0

sum:2

sum:1

sum:0

sum:3

sum:4

sum:5

sum:8

sum:7

sum:6

sum:10

sum:9

………………

後面就省略了,每次執行的結果應該也不一樣。

後來思考了一下原因,可能是每個執行緒得到的物件不是同乙個物件,於是在getinstance方法加入執行緒鎖。

public

static synchronized counter getinstance()

system.out.println("sum:"+sum++);

return counter;

}

這樣看來問題似乎解決了,但是似乎這樣的做法會效能很不好

如果應用程式總是建立並且使用單件例項,或者在建立和執行時不是很大的運算,可以這樣修改**:

public

class counter

public

static synchronized counter getinstance()

}

這樣的寫法,jvm虛擬機器在載入這個類時會馬上建立這個類唯一的例項,保證任何執行緒訪問前都會先建立這個例項,使用的也都是這個例項。

還有一種寫法就是利用雙重檢查枷鎖,在getinstance中減少使用同步。會先檢查例項是否已經被建立,如果沒有被建立才會進行同步。寫法如下:

public

class counter

public

static synchronized counter getinstance()

}system.out.println("sum:" + sum++);

return counter;

}}

測試結果也是正常的0到99

volatile不適用於jdk1.4以前。

總結:

不可以把單例類當成父類設計出子類。因為繼承單例類的構造器是私有的,不能用似有構造器來擴充套件類,所以必須把構造器變成共有的,但是變成共有的之後,就不能保證只有乙個例項了。還有乙個問題就是,單例的實現是利用靜態變數,直接結成會導致所有派生類共同使用乙個例項變數。

Java設計模式 單例模式

單例模式 singleton 顧名思義,就是乙個類只有乙個例項。作為物件的建立模式,單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。顯然單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。從具體...

java設計模式 單例模式

這個模式是很有意思,而且比較簡單,但是我還是要說因為它使用的是如此的廣泛,如此的有人緣,單例就是單 一 獨苗的意思,那什麼是獨乙份呢?你的思維是獨乙份,除此之外還有什麼不能山寨的呢?我們舉個比較難複製的物件 皇帝中國的歷史上很少出現兩個皇帝並存的時期,是有,但不多,那我們就認為皇帝是個單例模式,在這...

java設計模式 單例模式

單例模式介紹 單例模式分 懶漢式單例 餓漢式單例。單例模式有一下特點 1 單例類只能有乙個例項。2 單例類必須自己自己建立自己的唯一例項。3 單例類必須給所有其他物件提供這一例項。單例模式確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。單例有併發問題,只有乙個例項,多個執行緒就可能同...