Java設計模式GOF之單例模式

來源:互聯網
上載者:User

標籤:final   run   thread   java設計模式   單例對象   類載入   rto   imp   多線程   

一、單例模式(Singleton)

1、單例模式應用情境:

  ①Servlet
  ②工作管理員
  ③連結池
  ④Spring中每個 bean 預設是單例
  ⑤網站計數器

2、單例要求

  ①構造器私人
  ②私人的靜態變數
  ③公用的靜態可以訪問私人的靜態變數的方法

結論:由結果可以得知單例模式為一個物件導向的應用程式提供了對象惟一的訪問點,不管它實現何種功能,整個應用程式都會同享一個執行個體對象。
二、單例模式的實現方式

1、餓漢式
  安全執行緒、立即載入、資源使用率低、調用效率高

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton01
* @describe 餓漢式實現單例模式
* @author 張富昌
* @date 2017年3月27日上午8:40:02
*/
public class Singleton01 {

  // 天然的安全執行緒的,類載入是立即載入這個執行個體
  private static Singleton01 instance = new Singleton01();

  / 構造器私人化
  private Singleton01() {

  }

  // 方法沒有同步,效率比較高
  public static Singleton01 getInstance() {
    return instance;
  }
}



2、懶漢式
  安全執行緒、消極式載入、資源使用率高、調用效率低

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton02
* @describe 懶漢式實現單例模式
* @author 張富昌
* @date 2017年3月27日上午8:45:42
*/
public class Singleton02 {

  private static Singleton02 instance = null;

  //構造其私人化
  private Singleton02() {
  }

  //公用,同步,靜態
  public static synchronized Singleton02 getInstance() {
    if (instance == null) {
      instance = new Singleton02();
    }
    return instance;
  }
}


3、雙重檢索式
  安全執行緒、消極式載入、資源使用率高、調用效率高、但不穩定

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton03
* @describe 雙重檢測鎖式實現單例模式(不建議使用)
* @author 張富昌
* @date 2017年3月27日上午8:52:59
*/
public class Singleton03 {

  private static Singleton03 instance = null;

  private Singleton03() {

  }

  public static Singleton03 getInstance() {
    if (instance == null) {
      Singleton03 sc;
      synchronized (Singleton03.class) {
        sc = instance;
        if (sc == null) {
          synchronized (Singleton03.class) {
            if (sc == null) {
              sc = new Singleton03();
            }
          }
          instance = sc;
        }
      }
    }
    return instance;
  }

}


4、靜態內部類式(相比於懶漢式更好)
  安全執行緒、消極式載入、資源使用率高、調用效率高

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton04
* @describe 靜態內部類式實現單例模式
* @author 張富昌
* @date 2017年3月27日上午8:54:40
*/
public class Singleton04 {

  // 構造器私人化
  private Singleton04() {

  }

  // 靜態內部類
  private static class StaticInnerClass {
    private static final Singleton04 INSTANCE = new Singleton04();
  }

  public static Singleton04 getInstance() {
    return StaticInnerClass.INSTANCE;
  }

}


5、枚舉單例式(相比於餓漢式更好)
  安全執行緒、立即載入、可以天然的防止反射和還原序列化

package cn.com.zfc.gof01.singleton;

/**
*
* @title Singleton05
* @describe 枚舉式實現單例模式
* @author 張富昌
* @date 2017年3月27日上午9:01:59
*/
public enum Singleton05 {
  // 單例對象
  INSTANCE;

  // 如果要對該單例對象進行額外的操作,則加入方法
  public void singlrtonOperation() {

  }

}

三、測試多線程環境下五種建立單例模式的效率

package cn.com.zfc.gof01.singleton.test;

import java.util.concurrent.CountDownLatch;

import cn.com.zfc.gof01.singleton.Singleton05;

/**
*
* @title SingletonTest
* @describe 測試多線程環境下五種建立單例模式的效率
* @author 張富昌
* @date 2017年3月27日上午9:24:58
*/
public class SingletonTest {
  public static void main(String[] args) throws Exception {

    long start = System.currentTimeMillis();
    int threadNum = 10;
    // A synchronization aid that allows one or more threads to wait until a
    // set of operations being performed in other threads completes.
    // 計數器(一個線程執行完成就減1)
    final CountDownLatch countDownLatch = new CountDownLatch(threadNum);

    for (int i = 0; i < threadNum; i++) {
      // 多線程測試
      new Thread(new Runnable() {
        @Override
        public void run() {

          for (int i = 0; i < 1000000; i++) {
            // 餓漢式,
            // Object o = Singleton01.getInstance();
            // 懶漢式,最慢
            // Object o = Singleton02.getInstance();
            // 雙重檢測鎖式,不穩定,不建議使用
            // Object o = Singleton03.getInstance();
            // 靜態內部類
            // Object o = Singleton04.getInstance();
            // 枚舉式
            Object o = Singleton05.INSTANCE;
          }

          // 一個線程執行完成就減1
          countDownLatch.countDown();
        }
      }).start();
    }

    // 阻塞
    countDownLatch.await(); // main線程阻塞,直到計數器變為0,才會繼續往下執行!

    long end = System.currentTimeMillis();
    System.out.println("總耗時:" + (end - start));
  }
}

四、什麼是安全執行緒?

  如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程啟動並執行結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是安全執行緒的。

  或者說:一個類或者程式所提供的介面對於線程來說是原子操作,或者多個線程之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題,那就是安全執行緒的。

Java設計模式GOF之單例模式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.