【GOF23設計模式】單例模式

来源:http://www.cnblogs.com/erbing/archive/2016/08/24/5802401.html
-Advertisement-
Play Games

來源:http://www.bjsxt.com/ 一、【GOF23設計模式】_單例模式、應用場景、餓漢式、懶漢式 1、GOF23設計模式 2、單例模式 3、餓漢式 4、懶漢式 二、【GOF23設計模式】_單例模式、雙重檢查鎖式、靜態內部類式、枚舉式、UML類圖 雙重檢測鎖實現 靜態內部類實現 枚舉實 ...


來源:http://www.bjsxt.com/ 
一、【GOF23設計模式】_單例模式、應用場景、餓漢式、懶漢式

1、GOF23設計模式 
GOF23設計模式

2、單例模式 
單例模式

單例模式

3、餓漢式 
餓漢式

複製代碼
 1 package com.test.singleton;
 2 /**
 3  * 測試餓漢式單例模式
 4  */
 5 public class SingletonDemo01 {
 6 
 7     //類初始化時,立即載入這個對象(沒有延時載入的優勢)。載入類時,天然的是線程安全的!
 8     private static SingletonDemo01 instance = new SingletonDemo01();
 9 
10     private SingletonDemo01(){//私有化構造器
11     }
12 
13     //方法不用同步,調用效率高!
14     public static SingletonDemo01 getInstance(){
15         return instance;
16     }
17 }
複製代碼

4、懶漢式 
懶漢式

複製代碼
 1 package com.test.singleton;
 2 /**
 3  * 測試懶漢式單例模式
 4  */
 5 public class SingletonDemo02 {
 6 
 7     //類初始化時,不初始化這個對象(延時載入,真正用的時候再創建)
 8     private static SingletonDemo02 instance;
 9 
10     private SingletonDemo02(){//私有化構造器
11     }
12 
13     //方法同步,調用效率低!
14     public static synchronized SingletonDemo02 getInstance(){
15         if(null==instance){
16             instance = new SingletonDemo02();
17         }
18         return instance;
19     }
20 }
複製代碼

二、【GOF23設計模式】_單例模式、雙重檢查鎖式、靜態內部類式、枚舉式、UML類圖

雙重檢測鎖實現 
雙重檢測鎖實現

複製代碼
 1 package com.test.singleton;
 2 /**
 3  * 測試雙重檢測鎖式單例模式
 4  */
 5 public class SingletonDemo03 {
 6 
 7     //類初始化時,不初始化這個對象(延時載入,真正用的時候再創建)
 8     private static SingletonDemo03 instance;
 9 
10     private SingletonDemo03(){//私有化構造器
11     }
12 
13     //調用效率低!
14     public static SingletonDemo03 getInstance(){
15         if(null==instance){
16             SingletonDemo03 sc;
17             synchronized(SingletonDemo03.class){
18                 sc = instance;
19                 if(null==sc){
20                     synchronized (SingletonDemo03.class) {
21                         if(null==sc){
22                             sc = new SingletonDemo03();
23                         }
24                     }
25                     instance = sc;
26                 }
27             }
28         }
29         return instance;
30     }
31 }
複製代碼

靜態內部類實現 
靜態內部類實現

複製代碼
 1 package com.test.singleton;
 2 /**
 3  * 測試靜態內部類實現單例模式
 4  * 這種方式:線程安全,調用效率高,並且實現了延時載入!
 5  */
 6 public class SingletonDemo04 {
 7 
 8     private static class SingletonClassInstance {
 9         private static final SingletonDemo04 instance = new SingletonDemo04();
10     }
11 
12     private SingletonDemo04(){//私有化構造器
13     }
14 
15     //方法沒有同步,調用效率高!
16     public static SingletonDemo04 getInstance(){
17         return SingletonClassInstance.instance;
18     }
19 }
複製代碼

枚舉實現 
枚舉實現

複製代碼
 1 package com.test.singleton;
 2 /**
 3  * 測試枚舉式實現單例模式(沒有延時載入)
 4  */
 5 public enum SingletonDemo05 {
 6 
 7     //這個枚舉元素,本身就是單例對象!
 8     INSTANCE;
 9 
10     //添加自己需要的操作!
11     public void singletonOperation(){
12     }
13 }
複製代碼 複製代碼
 1 package com.test.singleton;
 2 
 3 public class Client {
 4     public static void main(String[] args) {
 5         SingletonDemo01 s1 = SingletonDemo01.getInstance();
 6         SingletonDemo01 s2 = SingletonDemo01.getInstance();
 7         System.out.println(s1==s2);//true
 8 
 9         SingletonDemo03 s3 = SingletonDemo03.getInstance();
10         SingletonDemo03 s4 = SingletonDemo03.getInstance();
11         System.out.println(s3==s4);//true
12 
13         System.out.println(SingletonDemo05.INSTANCE==SingletonDemo05.INSTANCE);//true
14     }
15 }
複製代碼

五種單例模式實現 
五種單例模式實現

三、【GOF23設計模式】_單例模式、反射和反序列化漏洞和解決方案、多線程環境測試、CountDownLatch同步類的使用

單例模式

複製代碼
 1 package com.test.singleton;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileOutputStream;
 5 import java.io.ObjectInputStream;
 6 import java.io.ObjectOutputStream;
 7 import java.lang.reflect.Constructor;
 8 
 9 /**
10  * 測試反射和反序列化破解單例模式
11  */
12 public class Client2 {
13     public static void main(String[] args) throws Exception {
14         SingletonDemo06 s1 = SingletonDemo06.getInstance();
15         SingletonDemo06 s2 = SingletonDemo06.getInstance();
16         System.out.println(s1);
17         System.out.println(s2);
18 
19         //通過反射的方式直接調用私有構造器
20 /*      Class<SingletonDemo06> clazz = (Class<SingletonDemo06>) Class.forName("com.test.singleton.SingletonDemo06");
21         Constructor<SingletonDemo06> c = clazz.getDeclaredConstructor(null);
22         c.setAccessible(true);//訪問私有,破解單例
23         SingletonDemo06 s3 = c.newInstance();
24         SingletonDemo06 s4 = c.newInstance();
25         System.out.println(s3);//SingletonDemo06的私有構造器中加了代碼防止破解
26         System.out.println(s4);*/
27 
28         //通過反序列化的方式構造多個對象
29         FileOutputStream fos = new FileOutputStream("g:/java/test/a.txt");
30         ObjectOutputStream oos = new ObjectOutputStream(fos);
31         oos.writeObject(s1);
32         oos.close();
33         fos.close();
34 
35         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("g:/java/test/a.txt"));
36         SingletonDemo06 s3 = (SingletonDemo06) ois.readObject();
37         System.out.println(s3);//SingletonDemo06定義了readResolve()防止破解
38     }
39 }
複製代碼 複製代碼
 1 package com.test.singleton;
 2 
 3 import java.io.ObjectStreamException;
 4 import java.io.Serializable;
 5 
 6 /**
 7  * 測試懶漢式單例模式(如何防止反射和反序列化漏洞)
 8  */
 9 public class SingletonDemo06 implements Serializable{
10 
11     //類初始化時,不初始化這個對象(延時載入,真正用的時候再創建)
12     private static SingletonDemo06 instance;
13 
14     private SingletonDemo06(){//私有化構造器
15         if(instance!=null){//防止反射破解單例(對象.setAccessible(true);)
16             throw new RuntimeException();
17         }
18     }
19 
20     //方法同步,調用效率低!
21     public static synchronized SingletonDemo06 getInstance(){
22         if(null==instance){
23             instance = new SingletonDemo06();
24         }
25         return instance;
26     }
27 
28     //反序列化時,如果定義了readResolve()則直接返回此方法指定的對象。而不需要單獨再創建新對象!
29     private Object readResolve() throws ObjectStreamException{
30         return instance;
31     }
32 }
複製代碼

五種單例模式在多線程環境下的效率測試

複製代碼
 1 package com.test.singleton;
 2 
 3 import java.util.concurrent.CountDownLatch;
 4 
 5 /**
 6  * 測試多線程環境下五種創建單例模式的效率
 7  */
 8 public class Client3 {
 9     public static void main(String[] args) throws Exception{
10 
11         int threadNum = 10;
12         final CountDownLatch countDownLatch = new CountDownLatch(threadNum); 
13 
14         long start = System.currentTimeMillis();
15         for(int i=0;i<10;i++){
16             new Thread(new Runnable(){
17                 @Override
18                 public void run() {
19                     for (int i = 0; i < 1000000; i++) {
20                         Object o = SingletonDemo01.getInstance();//分別測試幾種單例模式的效率
21                         //Object o = SingletonDemo05.INSTANCE;
22                     }
23 
24                     countDownLatch.countDown();//計數器減1
25                 }
26             }).start();
27         }
28 
29         countDownLatch.await();//main線程阻塞,直到計數器變為0,才會繼續往下執行!
30 
31         long end = System.currentTimeMillis();
32         System.out.println("總耗時:" + (end-start));
33     }
34 }
複製代碼
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 好久沒有寫博客了,上次發表博客還是在5月的時候,主要是4月多入職的新公司,5月份就開始做項目一直忙到這個月的中旬項目上線才偷得浮生半日閑,但是項目上線後客戶還是隔三差五的提個問題,不是改BUG就是添加新的東西,本來想著一邊看編程思想一邊把每章的讀後感寫出來發出來的,但是天天忙著加班雖然也抽時 ...
  • 目前業界流行的分散式消息隊列系統(或者可以叫做消息中間件)種類繁多,比如,基於Erlang的RabbitMQ、基於Java的ActiveMQ/Apache Kafka、基於C/C++的ZeroMQ等等,都能進行大批量的消息路由轉發。它們的共同特點是,都有一個消息中轉路由節點,按照消息隊列裡面的專業術 ...
  • 1、視C++為一個語言聯邦 C、object-oriented C++、template C++、STL 2、儘可能使用const: 1)關鍵字const出現的星號左邊,表示被指物事常量;如果出現在星號右邊,表示指針自身是常量;如果出現在兩邊,表示被指物和指針都是常量。 2)stl迭代器中申明迭代器 ...
  • 1. Visual C++ Redistributable for Visual Studio 2015系統要求:Windows 7情況下必須是Windows 7 with SP1.或者Windows10 2.系統檢測方法:命令行輸入winver.exe回車,如果你的windows版本是7600,需 ...
  • Canvas 設置開始繪圖位置:ctx.moveTo(x,y); 設置直線到的位置:ctx.lineTo(x,y); 描邊繪製:ctx.stroke(); 填充繪製:ctx.fill(); 自動閉合路徑:ctx.closePath(); 開啟新的繪製:ctx.beginPath(); 設置描邊顏色: ...
  • 1. Dubbo是什麼? 只是一個框架 Hibernate是持久層框架,SpringMVC是MVC的框架,而Dubbo是分散式服務框架。 是框架而不是服務 所以不是像Tomcat或Memcached可以單獨啟動,它必須依附於應用才有意義。引入dubbo.jar的應用,並完成適合的配置後,這個應用就成 ...
  • 之前對依賴註入的概念一直感到模糊,直到看了這篇文章:http://www.iteye.com/topic/1122835 引述: IoC(控制反轉:Inverse of Control)是Spring容器的內核,AOP、聲明式事務等功能在此基礎上開花結果。但是IoC這個重要的概念卻比較晦澀隱諱,不容 ...
  • 來源:http://www.bjsxt.com/ 一、【GOF23設計模式】_簡單工廠模式詳解、面向對象設計原則、開閉原則、依賴反轉原則、迪米特法則 沒有工廠模式的情況 簡單工廠模式的情況 或者 二、【GOF23設計模式】_工廠方法模式詳解 三、【GOF23設計模式】_抽象工廠模式詳解 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...