《23天設計模式之單例模式》這是個人第二篇博客。在接下來的23天內,咱們將23種設計模式都去了解一下。今天咱們就來學習最簡單的單例模式。java
在學習設計模式以前咱們不可避免要去想爲何要學習這個東西,它是用來幹嗎的?算法
整體分爲3大類:編程
public class Singleton { //靜態單例 private static final Singleton INSTANCE = new Singleton(); //私有的構造方法 private Singleton(){}; // 獲取單例的靜態方法 public static Singleton getInstance() { return INSTANCE; } }
public class Singleton { //調用getInstance()方法時初始化 private static Singleton instance; //輸出文字看這個構造方法被調用了幾回 private Singleton(){ System.out.println(Thread.currentThread().getName() + "調用了構造方法"); }; //加了判空 public static Singleton getInstance(){ if (instance == null) { instance = new Singleton(); } return instance; } //使用多線程測試構造方法被調用了幾回。正常來講應該只調用一次。 public static void main(String[] args) { for (int i = 0; i < 4; i++) { new Thread(Singleton::getInstance).start(); } } } //輸出以下: Thread-1調用了構造方法 Thread-2調用了構造方法 Thread-0調用了構造方法
分析:windows
public class Singleton { //volatile禁止指令重排優化 private static volatile Singleton instance; private Singleton(){ System.out.println(Thread.currentThread().getName() + "調用了構造方法"); }; //DCL雙重檢鎖 public static Singleton getInstance(){ if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } public static void main(String[] args) { for (int i = 0; i < 4; i++) { new Thread(Singleton::getInstance).start(); } } } //輸出: Thread-0調用了構造方法
分析:設計模式
不管執行多少次main函數,始終只有一條線程能調用構造函數。安全
指令重排:編譯器、JVM 或者 CPU 都有可能出於優化等目的,對於實際指令執行的順序進行調整。多線程
爲何要禁止指令重排:多線程環境中線程交替執行,因爲編譯器指令重排的存在,兩個線程使用的變量可否保證一致性是沒法確認的,結果沒法預測。函數
public class Singleton { private Singleton(){ }; public static Singleton getInstance() { return InnerClass.INSTANCE; } //靜態內部類 public static class InnerClass { private static final Singleton INSTANCE = new Singleton(); } }
public enum Singleton { INSTANCE; public Singleton getInstance(){ return INSTANCE; } }
以上就是單例模式的主要內容。接下來咱們瞭解如下單例模式的常見應用場景。oop
Windows的Task Manager(任務管理器)就是很典型的單例模式學習
windows的Recycle Bin(回收站)就是典型的單例應用。在整個系統運行過程當中,回收站一直維護着僅有的一個實例。
網站的計數器,通常也是採用單例模式實現,不然難以同步。
多線程的線程池的設計通常也是採用單例模式,這是因爲線程池要方便對池中的線程進行控制。
感謝您花時間閱讀個人博客,以上就是我對單例模式的一些理解,如有不對之處,還望指正,期待與您交流。
本篇博文系原創,僅用於我的學習,轉載請註明出處。