前言 **基礎篇鏈接:**https://www.cnblogs.com/xiegongzi/p/16229678.html 3.9、延遲隊列 - 重要 3.9.1、延遲隊列概念 這個玩意兒要表達的意思其實已經見過了,就是死信隊列中說的TTL消息過期,但是文字表達得換一下 所謂的延遲隊列:就是用來存 ...
轉自:
http://www.java265.com/JavaCourse/202109/1153.html
下文是筆者編寫的單例模式實現的八種方式,如下所示:
單例模式的簡介
我們將一個類在當前進程中只有一個實例的這種模式,稱之為“單例模式”
那麼Java代碼如何實現一個單例模式呢?下文將一一到來,如下所示:
單例模式的註意事項: 1.單例模式在一個進程中只有一個實例 2.單例類通常由自己創建自身的實例 3.單例類給其他對象提供的都是同一個實例
測試代碼
package com.java265.Singleton; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("------單例模式-----"); //創建100個線程進行測試 for(int i=0;i<100;i++) { new Thread(()->{ System.out.println(Single01.getInstance()); }).start(); } } }
單例實現模式1
餓漢式單例模式:
直接使用一個靜態變數,在JVM載入類時,生成一個單例實例 如下
package com.java265.Singleton; public class Single01 { private static final Single01 INSTANCE = new Single01(); private Single01() {} public static Single01 getInstance () { return INSTANCE; } }
使用static靜態代碼塊生成一個單例類
package com.java265.Singleton; public class Single02 { private static final Single02 INSTANCE; static { INSTANCE = new Single02(); } private Single02() {} public static Single02 getInstance() { return INSTANCE; } public void t() { System.out.println("Single02 t方法" + ""); } }
使用判斷的方式,創建單例模式,
但是此處不是一個線程安全的創建方式
package com.java265.Singleton; /* * 這是一個線程不安全的創建單例模式的方式 * 這是一個懶漢式的創建單例模式的方式 * */ public class Single03 { private static Single03 INSTANCE; private Single03() { } public static Single03 getInstance() { if(INSTANCE ==null) { // 多個線程都會被卡在此處, // 當sleep運行完畢後,多個線程會同時創建實例,此處的代碼是產生線程不安全的根源 try { Thread.sleep(100); }catch(InterruptedException e) { } INSTANCE = new Single03(); } return INSTANCE; } }
使用 synchronized為方法加上鎖,使其線程安全
package com.java265.Singleton; public class Single04 { private static volatile Single04 INSTANCE; private Single04() { } /* * 懶漢式生成單例實例 此處使用 synchronized 安全鎖 */ public static synchronized Single04 getInstance() { if(INSTANCE ==null) { try { Thread.sleep(100); }catch(InterruptedException e) { } INSTANCE = new Single04(); } return INSTANCE; } }
減少鎖粒度,將synchronized關鍵字直接加在方法內部具體的位置上
package com.java265.Singleton; public class Single05 { private static Single05 INSTANCE; private Single05() { } public static Single05 getInstance() { if(INSTANCE ==null) { /* * 將鎖直接加到方法體裡面 此時出現了一個新的問題 當所有的線程都堵塞在此處,也會創建多個實例 */ synchronized(Single05.class) { try { Thread.sleep(100); }catch(InterruptedException e) { } INSTANCE = new Single05(); } } return INSTANCE; } }
將synchronized鎖放入在方法體中,同時使用雙重檢查,避免創建多個實例
package com.java265.Singleton; public class Single06 { private static Single06 INSTANCE; private Single06() { } public static Single06 getInstance() { if(INSTANCE ==null) { synchronized(Single06.class) { try { Thread.sleep(100); }catch(InterruptedException e) { } if(INSTANCE == null) { INSTANCE = new Single06(); } } } return INSTANCE; } }
使用靜態內部類的方式創建一個單例對象
此方式主要藉助JVM載入類時,內部類不會被載入
當我們使用內部類的時,才會被載入,此時由JVM保證靜態內部類的唯一性
package com.java265.Singleton; /* * 採用內部類的方式實現一個單例模式 * */ public class Single07 { private Single07() { } private static class Single07Holder { private final static Single07 INSTANCE = new Single07(); } public static Single07 getInstance() { return Single07Holder.INSTANCE; } }
使用枚舉創建一個靜態內部類
package com.java265.Singleton; /* * 採用枚舉實現一個單例模式 * */ public enum Single08 { INSTANCE; public static Single08 getInstance() { return INSTANCE; } }