欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

java單例的五種實(shí)現(xiàn)方式及其性能分析

java 單例的五種實(shí)現(xiàn)方式及其性能分析

創(chuàng)新互聯(lián)成都企業(yè)網(wǎng)站建設(shè)服務(wù),提供網(wǎng)站制作、做網(wǎng)站網(wǎng)站開發(fā),網(wǎng)站定制,建網(wǎng)站,網(wǎng)站搭建,網(wǎng)站設(shè)計(jì),成都響應(yīng)式網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì)師打造企業(yè)風(fēng)格網(wǎng)站,提供周到的售前咨詢和貼心的售后服務(wù)。歡迎咨詢做網(wǎng)站需要多少錢:18980820575

序言

在23種設(shè)計(jì)模式中,單例是最簡(jiǎn)單的設(shè)計(jì)模式,但是也是很常用的設(shè)計(jì)模式。從單例的五種實(shí)現(xiàn)方式中我們可以看到程序員對(duì)性能的不懈追求。下面我將分析單例的五種實(shí)現(xiàn)方式的優(yōu)缺點(diǎn),并對(duì)其在多線程環(huán)境下的性能進(jìn)行測(cè)試。

實(shí)現(xiàn)

單例模式適用于資源占用較多的類,保證一個(gè)類只有一個(gè)實(shí)例即單例。通用的做法就是構(gòu)造器私有化,提供一個(gè)全局的訪問點(diǎn),返回類的實(shí)例。

uml圖:

java 單例的五種實(shí)現(xiàn)方式及其性能分析

1.餓漢式

代碼實(shí)現(xiàn):

package com.zgh.gof23.singleton;
/**
 * 餓漢式
 * @author yuelin
 *
 */
public class SingleDemo {
 private static SingleDemo instance = new SingleDemo();
 //私有化構(gòu)造器
 private SingleDemo() {
 //防止其他通過反射調(diào)用構(gòu)造方法,破解單例
 if (instance != null) {
  throw new RuntimeException();
 }
 }

 //對(duì)外提供統(tǒng)一的訪問點(diǎn)
 public static SingleDemo getInstance() {
 return instance;
 }
}

優(yōu)點(diǎn)

1.實(shí)例的初始化由JVM裝載類的時(shí)候進(jìn)行,保證了線程的安全性
2.實(shí)現(xiàn)簡(jiǎn)單方便
3.實(shí)例的訪問效率高

缺點(diǎn)

1.不能實(shí)現(xiàn)懶加載,如果不調(diào)用getInstance(),那么這個(gè)類就白白的占據(jù)內(nèi)存,資源的利用率不高
注意

1.防止通過反射調(diào)用構(gòu)造方法破解單例模式。
2.防止通過反序列產(chǎn)生新的對(duì)象。

2.懶漢式

代碼實(shí)現(xiàn):

package com.zgh.gof23.singleton;

/**
 * 懶漢式實(shí)現(xiàn)單例
 * 
 * @author zhuguohui
 *
 */
public class SingleDemo2 {
 // 此處并不初始化實(shí)例
 private static SingleDemo2 instance;

 private SingleDemo2() {
 if (instance != null) {
  throw new RuntimeException();
 }
 }

 /**
 * 當(dāng)調(diào)用此方法的時(shí)候才初始化實(shí)例, 為了實(shí)現(xiàn)線程安全,需要使用同步方法
 * 
 * @return
 */
 public static synchronized SingleDemo2 getInstance() {
 if (instance == null) {
  instance = new SingleDemo2();
 }
 return instance;
 }
}

優(yōu)點(diǎn)

1.只有使用這個(gè)類的時(shí)候才初始化實(shí)例,優(yōu)化了資源利用率

缺點(diǎn)

1.為了實(shí)現(xiàn)線程安全,使用了同步方法獲取,增加了訪問的開銷

注意

1.防止通過反射調(diào)用構(gòu)造方法破解單例模式。
2.防止通過反序列產(chǎn)生新的對(duì)象。

3.雙重檢查

代碼實(shí)現(xiàn):

package com.zgh.gof23.singleton;

/**
 * 雙重檢查
 * 
 * @author zhuguohui
 *
 */
public class SingleDemo3 {
 private static SingleDemo3 instance;

 private SingleDemo3() {
 if (instance != null) {
  throw new RuntimeException();
 }
 }

 public static SingleDemo3 getInstance() {
 //第一重檢查,提高效率
 if (instance == null) {
  synchronized (SingleDemo3.class) {
  //第二重檢查保證線程安全
  if (instance == null) {
   instance = new SingleDemo3();
  }
  }
 }
 return instance;
 }
}

優(yōu)點(diǎn)

1.實(shí)現(xiàn)懶加載
2.通過縮小同步區(qū)域和第一次檢查提高訪問效率

缺點(diǎn)

1.為了實(shí)現(xiàn)線程安全,使用了同步方法獲取,增加了訪問的開銷

注意

1.防止通過反射調(diào)用構(gòu)造方法破解單例模式。
2.防止通過反序列產(chǎn)生新的對(duì)象。

4.靜態(tài)內(nèi)部類

代碼實(shí)現(xiàn):

/**
 * 靜態(tài)內(nèi)部類實(shí)現(xiàn)單例
 * 
 * @author zhuguohui
 *
 */
public class SingleDemo4 {
 private static SingleDemo4 instance;

 private static class SingleDemo4Holder {
 private static final SingleDemo4 instance = new SingleDemo4();
 }

 private SingleDemo4() {
 if (instance != null) {
  throw new RuntimeException();
 }
 }

 /**
 * 調(diào)用這個(gè)方法的時(shí)候,JVM才加載靜態(tài)內(nèi)部類,才初始化靜態(tài)內(nèi)部類的類變量。由于由JVM初始化,保證了線程安全性,
 * 同時(shí)又實(shí)現(xiàn)了懶加載
 * @return
 */
 public static SingleDemo4 getInstance() {
 return SingleDemo4Holder.instance;
 }
}

優(yōu)點(diǎn)

1.即實(shí)現(xiàn)了線程安全,又實(shí)現(xiàn)了懶加載

缺點(diǎn)

2.實(shí)現(xiàn)稍顯復(fù)雜

5.枚舉實(shí)現(xiàn)

代碼實(shí)現(xiàn):

/**
 * 枚舉實(shí)現(xiàn)單例
 * 枚舉由JVM實(shí)現(xiàn)其的單例性
 * @author zhuguohui
 *
 */
public enum SingleDemo5 {
 INSTANCE;
}

優(yōu)點(diǎn)

1.實(shí)現(xiàn)簡(jiǎn)單
2.線程安全
3.天熱對(duì)反射和反序列化漏洞免疫(由JVM提供)

缺點(diǎn)

2.不能實(shí)現(xiàn)懶加載

注意

1.防止通過反射調(diào)用構(gòu)造方法破解單例模式。
2.防止通過反序列產(chǎn)生新的對(duì)象。

測(cè)試

源碼

public class APP {
 public static void main(String[] args) {

 int threadCount = 100;
 long start = System.currentTimeMillis();
 final CountLock lock = new CountLock(threadCount);
 for (int i = 0; i < threadCount; i++) {
  new Thread(new Runnable() {

  @Override
  public void run() {
   for (int j = 0; j < 10000000; j++) {
   //通過更換此處,來測(cè)試不同單例實(shí)現(xiàn)方式在多線程環(huán)境下的性能
   SingleDemo5 demo = SingleDemo5.INSTANCE;
   }
   lock.finish();
  }
  }).start();

 }
 //等待所有線程執(zhí)行完
 lock.waitForWrok();
 long end = System.currentTimeMillis();
 System.out.println("總共耗時(shí)" + (end - start));
 }
}

為了統(tǒng)計(jì)所以線程執(zhí)行完需要的時(shí)間,我寫了一個(gè)工具類

package com.zgh.gof23.singleton;

public class CountLock {
 //線程的總數(shù)量
 private int count;

 public CountLock(int count) {
 this.count = count;
 }

 /**
 * 當(dāng)一個(gè)線程完成任務(wù)以后,調(diào)用一次這個(gè)方法
 */
 public synchronized void finish() {
 count--;
 if (count == 0) {
  notifyAll();
 }
 }

 /**
 * 需要等待其他線程執(zhí)行完的線程,調(diào)用此方法。
 */
 public synchronized void waitForWrok() {
 while (count > 0) {
  try {
  wait();
  } catch (InterruptedException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
  }
 }
 }
}

結(jié)果

五種單例實(shí)現(xiàn)方式,在100個(gè)線程下,每個(gè)線程訪問1千萬次實(shí)例的用時(shí).

Tables實(shí)現(xiàn)方式用時(shí)(毫秒)
1餓漢式13
2懶漢式10778
3雙重檢查15
4靜態(tài)內(nèi)部類14
5枚舉12

(*注意:由于不同電腦之間的性能差異,測(cè)試的結(jié)果可能不同)

總結(jié)

如果需要懶加載就使用靜態(tài)內(nèi)部類方式,如果不需要就使用枚舉方式。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持! 

標(biāo)題名稱:java單例的五種實(shí)現(xiàn)方式及其性能分析
新聞來源:http://chinadenli.net/article36/poogpg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序全網(wǎng)營(yíng)銷推廣、用戶體驗(yàn)、虛擬主機(jī)、品牌網(wǎng)站制作手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化