單例模式的風險

單 例 模 式 很 簡 單 , 就 是 在 構 造 函 數 中 多 了 加 一 個 構 造 函 數 , 訪 問 權 限 是 p r i v a t e 的 就 可 以 了 , 這 個 模
式 是 簡 單 , 但 是 簡 單 中 透 着 風 險 , 風 險 ? 什 麼 風 險 ? 在 一 個 B / S 項 目 中 , 每 個 H T T P R e q u e s t 請 求 到 J 2 E E的容器上後都創建了一個線程,每個線程都要創建同一個單例對象,怎麼辦?,好,我們寫一個通用的單例程序,然後分析一下:

 

 /**
     * 通用單例模式
     */
    @SuppressWarnings("all")
    public class SingletonPattern {
        private static SingletonPattern singletonPattern = null;  // 限制住不能直接產生一個實例

        private SingletonPattern() {
        }

        public SingletonPattern getInstance() {
            if (this.singletonPattern == null) {  // 如果還沒有實例,則創建一個
                this.singletonPattern = new SingletonPattern();
            }

            return this.singletonPattern;
        }
    }

 

我 們 來 看 加粗的 那 一 部 分 , 假 如 現 在 有 兩 個 線 程 A 和 線 程 B , 線 程 A 執 行 到 t h is.singleto nPattern = new SingletonPattern() , 正 在 申 請 內 存 分 配 , 可 能 需 要 0 . 0 0 1 微 秒 , 就 在 這 0 . 0 0 1 微 秒 之 內 , 線 程 B 執行 到

i f ( t h i s . s i n g l e t o n P a t t e r n = = n u l l ) , 你 說 這 個 時 候 這 個 判 斷 條 件 是 t r u e 還 是 f a l s e ? 是 t rue,那然 後 呢 ? 線 程 B 也 往 下 走 ,於 是 乎 就 在 內 存 中 就 有 兩 個 S i n g l e t o n P a t t e r n 的 實 例 了 ,看看是不是出問題了?

如果你這個單例是去拿一個序列號或者創建一個信號資源的時候,會怎麼樣?業務邏輯混亂!數據一致性校驗失敗!重要的是你從代碼上還看不出什麼問題,這纔是要命的!因爲這種情況基本上你是重現不了的,不寒而慄吧,那怎麼修改?有很多種方案,我就說一種,能簡單的、徹底解決問題的方案

/**
 * 通用單例模式
 */
    @SuppressWarnings("all")
    public class SingletonPattern {
        private static final SingletonPattern singletonPattern = new SingletonPattern();    // 限制住不能直接產生一個實例

        private SingletonPattern() {
        }

        public synchronized static SingletonPattern getInstance() {
            return singletonPattern;
        }

    }

直 接 n e w 一 個 對 象 傳 遞 給 類 的 成 員 變 量 s i n g l e t o n p a t t e r n , 你 要 的 時 候 g e t I n s tance()直接返回給
你,解決問題!
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章