<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 262,  comments - 221,  trackbacks - 0
    一、單例模式的陷阱

    設計模式中的單例模式應該是被大家使用最廣泛的模式之一,但網上關于單例模式的詬病也不少,最集中的就是:在多線程的環境下,單例模式有可能返回不止一個的對象。那么到底為什么會出現這種情況呢?下面我們來看單例模式的兩種實現方式

    方式一

    public class Singleton {

      //注意構造方法必須是私有的
          private Singleton(){}

      //在自己內部定義自己一個實例,是不是很奇怪?
      //注意這是private 只供內部調用

      private static Singleton instance = new Singleton();

      //這里提供了一個供外部訪問本class的靜態方法,可以直接訪問  
      
    public static Singleton getInstance() {
        return instance;   
       }
    }


    方式二
    public class Singleton {

      private static Singleton instance = null;

      
    public static synchronized Singleton getInstance() {

          //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次     
          //使用時生成實例!
          if (instance==null)
       
         instance=new Singleton();
                return instance;
          }
           }
    }


    方式二就是我們說的:滯后初始化(Lazy Initialization)。為什么會有滯后初始化這種實現方式出現呢?我們可用看到在第一種實現方式中無法向單例模式的構造方法傳遞參數,而使用滯后初始化的方式,我們可用在調用getInstance()方法的時候向方法中傳遞參數。


    凡事有好處必然有壞處,滯后初始化的一個弊病就是在多線程或分布式的環境下有可能出現混亂:

    “有時在某些情況下,使用Singleton并不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分布式系統中使用也要注意這種情況,因為EJB是跨服務器,跨JVM的。” --摘自www.jdon.com-《GoF 23種設計模式解析》

    “在多線程環境下,我們無法保證一個方法能夠持續運行到結束,其他線程的方法才開始運行。因而可能存在這樣一種情形:兩個線程幾乎同時嘗試初始化單例類。假設第一個方法發現單例為空,而第二個方法在此刻開始運行,它也會發現該單例為空。接下來,這兩個方法都將對該單例進行初始化。”  --摘自《Java設計模式》


    二、單例模式在多線程下的安全實現

    《Java并發編程》一書建議使用屬于當前類的鎖進行同步,代碼如下:

    public class Singleton {

        private static Singleton instance = null;
      // 注意這里的static非常重要,如果為對象變量則因為存在多份拷貝而起不到限制的作用
        private static Object classLock = Singleton.class;

         public static Singleton getInstance() {

          //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次     
          //使用時生成實例!
              synchronized(classLock){
                  if (instance==null)
              instance=new Singleton();
                  return instance;
              } 
              }      
         }
    }

    在第一個線程開始滯后初始化的時候,如果有另一線程也準備開始初始化,這時候,第二個線程將停止執行,等待獲取對象classLock的鎖。當第二個線程獲取這個鎖并開始執行初始化的時候,它會發現該單例已不再為空(因為只存在該類的唯有實例,我們可以使用單個靜態鎖)

    三、使用單例模式的另外一些注意點

    ·單例模式類不能實現Clonable接口,以防被克隆而產生多個實例

    ·單例模式類不能實現Serializable接口,以防被序列化而產生多個實例



    -------------------------------------------------------------
    生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
    posted on 2008-01-03 22:31 Paul Lin 閱讀(1224) 評論(0)  編輯  收藏 所屬分類: 模式與重構
    <2008年1月>
    303112345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    常用鏈接

    留言簿(21)

    隨筆分類

    隨筆檔案

    BlogJava熱點博客

    好友博客

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲欧洲国产经精品香蕉网| 亚洲成人动漫在线| 亚洲欧美日韩国产成人| 美丽的姑娘免费观看在线播放| 国产精品亚洲片在线| 西西人体免费视频| 久久国产亚洲精品麻豆| 国色精品va在线观看免费视频| 亚洲αv久久久噜噜噜噜噜| 国产色爽免费无码视频| 亚洲av永久无码制服河南实里| 日韩精品在线免费观看| 4444亚洲国产成人精品| 青青草免费在线视频| 亚洲欧美成人av在线观看| 日日操夜夜操免费视频| 免费一级特黄特色大片| 亚洲理论电影在线观看| 99久热只有精品视频免费看| 亚洲精品熟女国产| 成人免费毛片观看| 美女无遮挡免费视频网站 | 一个人看的hd免费视频| 亚洲中文字幕在线观看| 四虎影视成人永久免费观看视频 | 亚洲午夜精品第一区二区8050| 国产免费伦精品一区二区三区| 亚洲av不卡一区二区三区| 动漫黄网站免费永久在线观看 | 亚洲不卡影院午夜在线观看| 国产在线观看免费视频播放器| a级毛片高清免费视频就| 亚洲中文字幕无码av在线| 免费v片在线观看| 久久久久免费看黄a级试看| 四虎亚洲精品高清在线观看| 亚洲精品成人在线| 国产在线a免费观看| 又大又硬又粗又黄的视频免费看 | 老司机福利在线免费观看| 亚洲天堂在线播放|