Java設計模式GOF之單例模式

来源:http://www.cnblogs.com/zfc-java/archive/2017/04/02/6659579.html
-Advertisement-
Play Games

一、單例模式(Singleton) 1、單例模式應用場景: ①Servlet ②任務管理器 ③鏈接池 ④Spring中每個 bean 預設是單例 ⑤網站計數器 2、單例要求 ①構造器私有 ②私有的靜態變數 ③公共的靜態的可以訪問私有的靜態變數的方法 結論:由結果可以得知單例模式為一個面向對象的應用程 ...


一、單例模式(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));
  }
}

四、什麼是線程安全?

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

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文重點總結了編程學習方法,常用的dos命令,java三大技術架構,jdk和jre和jvm的關係以及path和classpath的區別。重點是jdk和jre和jvm的關係以及path和classpath的區別。 ...
  • 題目鏈接 Problem Description MG is a rich boy. He has n apples, each has a value of V(0<=V<=9). A valid number does not contain a leading zero, and these ...
  • 資料庫連接池類,用於獲取資料庫連接。利用單例模式保證所有的連接都只通過一個連接池管理。 DBUtil類,包裝DBPool,簡化使用 測試代碼,和不使用連接池的情況做對比 ...
  • 希望對大家學習或者使用python3能具有一定的參考價值。 __abs__ #返回一個數的絕對值 >>> num3=-22 >>> num3.__abs__() 22 __add__ #兩數相加 __and__ #兩數按位與操作 __bool__ #求一個數的布爾值 >>> num1=4 >>> n ...
  • 不要62 時間限制:1sec 記憶體限制:3MB 題目描述 杭州人稱那些傻乎乎粘嗒嗒的人為62(音:laoer)。 杭州交通管理局經常會擴充一些計程車車牌照,新近出來一個好消息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別計程車司機和乘客的心理障礙,更安全地服務大眾。不吉利的數字為所有含有 ...
  • 12:變幻的矩陣 12:變幻的矩陣 查看 提交 統計 提問 查看 提交 統計 提問 總時間限制: 1000ms 記憶體限制: 65536kB描述 有一個N x N(N為奇數,且1 <= N <= 10)的矩陣,矩陣中的元素都是字元。這個矩陣可能會按照如下的幾種變幻法則之一進行變幻(只會變幻一次)。 現 ...
  • 線性表之順序表 一、頭文件:SeqList.h //順序線性表的頭文件#include<iostream> const int MaxSize = 100;//定義順序表SeqList的模板類template<class DataType>class SeqList{public: //順序表無參構 ...
  • JSR330 DI JSR 330 ,提供了一種可重用的、可維護、可測試的方式來獲取Java對象。也稱為Dependency Injection 。 DI應該都不陌生,因為它就是Spring core之一。在Spring盛行後,Google也提供了一種DI實現:Guice。因為這兩個DI容器的盛行, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...