原文
主要介紹單例模式的一種寫法、注意事項(xiàng)、作用斋日、測(cè)試,以Java語言為例墓陈,下面代碼是目前見過最好的寫法:
public class Singleton {
private static volatile Singleton instance = null;
// private constructor suppresses
private Singleton(){
}
public static Singleton getInstance() {
// if already inited, no need to get lock everytime
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
1恶守、需要注意的點(diǎn)
其中需要注意的點(diǎn)主要有三點(diǎn)
(1) 私有化構(gòu)造函數(shù)
(2) 定義靜態(tài)的Singleton instance對(duì)象和getInstance()方法
(3) getInstance()方法中需要使用同步鎖synchronized (Singleton.class)防止多線程同時(shí)進(jìn)入造成instance被多次實(shí)例化可以看到上面在synchronized (Singleton.class)外又添加了一層if,這是為了在instance已經(jīng)實(shí)例化后下次進(jìn)入不必執(zhí)行synchronized (Singleton.class)獲取對(duì)象鎖贡必,從而提高性能句喜。
Ps: 也有實(shí)現(xiàn)使用的是private static Object obj = new Object();加上synchronized(obj)概耻,實(shí)際沒有必要多創(chuàng)建一個(gè)對(duì)象。synchronized(X.class) is used to make sure that there is exactly one Thread in the block.
2刷袍、單例的作用
單例主要有兩個(gè)作用
(1) 保持程序運(yùn)行過程中該類始終只存在一個(gè)示例
(2) 對(duì)于new性能消耗較大的類冻记,只實(shí)例化一次可以提高性能
3冒嫡、單例模式測(cè)試
單例模式可以使用多線程并發(fā)進(jìn)行測(cè)試抄囚,代碼如下:
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1);
int threadCount = 1000;
for (int i = 0; i < threadCount; i++) {
new Thread() {
@Override
public void run() {
try {
// all thread to wait
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// test get instance
System.out.println(Singleton.getInstance().hashCode());
}
}.start();
}
// release lock, let all thread excute Singleton.getInstance() at the same time
latch.countDown();
}
其中CountDownLatch latch為閉鎖泊藕,所有線程中都用latch.await();等待鎖釋放,待所有線程初始化完成使用latch.countDown();釋放鎖晋被,從而達(dá)到線程并發(fā)執(zhí)行Singleton.getInstance()的效果兑徘。