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

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

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

    回歸

    驀然回首,那人卻在燈火闌珊處

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      4 Posts :: 2 Stories :: 12 Comments :: 0 Trackbacks
          現(xiàn)在大多數(shù)Java軟件工程師面試都會(huì)問(wèn)到這個(gè)問(wèn)題:什么是單例模式(Singleton),能否寫出單例模式的示例代碼?單例模式是Gof中23個(gè)模式中最簡(jiǎn)單最容易入門的模式,學(xué)習(xí)它我們能更理性的感知模式的意義.

         [形成]

          Singleton Pattern 為什么會(huì)出現(xiàn)?在我們軟件開(kāi)發(fā)和架構(gòu)中,經(jīng)常遇到這樣的情形:我們需要一個(gè)類只能且僅能產(chǎn)生一個(gè)實(shí)例..比如表示一臺(tái)計(jì)算機(jī)的類,表示系統(tǒng)設(shè)定的類或者是表示窗口的類,還有為了節(jié)約資源,只讓產(chǎn)生一個(gè)實(shí)例..
         
          如何構(gòu)造這種情形?Singleton模式給我一個(gè)方案:


         [代碼示例]
          
          程序列表
       

    名稱

    說(shuō)明

    Singleton

    只有一個(gè)對(duì)象實(shí)例的類

    Main

    測(cè)試用的類



          [UML圖]
       
          

    [示例代碼和類的詮釋]

     1 package singleton;
     2 
     3 public class Singleton {
     4     private static Singleton singleton = new Singleton();
     5 
     6     private Singleton() {
     7         System.out.println("Create instance...");
     8     }
     9 
    10     public static Singleton getInstance() {
    11         return singleton;
    12     }
    13 }
    14 


              Singleton  Class:
                
                1.該類只能產(chǎn)生一個(gè)對(duì)象實(shí)例

                2.把該類的的singleton屬性設(shè)定為static再以Singleton;類的對(duì)象實(shí)例進(jìn)行初始化,這個(gè)初始化的過(guò)程僅加載Sington類的時(shí)候調(diào)用一次.(Line4) 

                3.把Singleton 類的構(gòu)造函數(shù)限定為private,目的是為了防止從非Singleton類(其他類)調(diào)用構(gòu)造函數(shù)來(lái)產(chǎn)生實(shí)例,如果通過(guò)new方式來(lái)產(chǎn)生Singleton實(shí)例,會(huì)出現(xiàn)編譯錯(cuò)誤.這樣做是為了保險(xiǎn)己見(jiàn).(Line6) 

                4.要得到Singleton實(shí)例的唯一方法就是調(diào)用類靜態(tài)方法getInstance().這個(gè)名字可以隨便取,只要方便理解就行.(Line 10) 

     1 package singleton;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         System.out.println("Start");
     7         Singleton obj1 = Singleton.getInstance();
     8         Singleton obj2 = Singleton.getInstance();
     9         if(obj1 == obj2){
    10             System.out.println("obj1和obj2是同一個(gè)對(duì)象實(shí)例");
    11         }else{
    12             System.out.println("obj1和obj2不是同一個(gè)對(duì)象實(shí)例");
    13         }
    14         System.out.println("End");
    15     }
    16 }
    17 


           Main Class
            1.該類是測(cè)試程序.
            2.程序通過(guò)getInstance()方式產(chǎn)生兩個(gè)obj1和obj2實(shí)例.(Line 7,Line 8)
            3.通過(guò)ojb1= =ojb2表達(dá)式來(lái)確定兩個(gè)對(duì)象是否相同,判定是否產(chǎn)生了Singleton的第二個(gè)示例.(Line9-12)
     

    示例程序的執(zhí)行結(jié)果
    Start
    Create instance...
    obj1和obj2是同一個(gè)對(duì)象實(shí)例
    End

             執(zhí)行結(jié)果含義:
                    1. 的確如此,obj1和obj2是Singleton類的同一個(gè)且唯一的對(duì)象實(shí)例. 
                    2.當(dāng)程序執(zhí)行后,第一次調(diào)用getInstance的時(shí)候會(huì)初始化Singleton類,同時(shí)也會(huì)初始化static字段,也同時(shí)產(chǎn)生產(chǎn)生了一個(gè)唯一對(duì)象實(shí)例.




          [拓展思考]
       
    如下的另一一個(gè)單例模式的程序有什么隱患?

     1 package singleton;
     2 
     3 public class Singleton2 {
     4     
     5     private static Singleton2 singleton = null;
     6     
     7     private Singleton2(){
     8         System.out.println("已產(chǎn)生對(duì)象實(shí)例");
     9     }
    10     public static Singleton2 getInstance(){
    11         if(singleton == null){
    12             singleton = new Singleton2();
    13         }
    14         return singleton;
    15     }
    16 
    17 }
    18 

        [解答]
    當(dāng)多線程同時(shí)調(diào)用Singleton2.getInstance()方法時(shí),可能會(huì)產(chǎn)生多個(gè)對(duì)象實(shí)例,例如
    public class Main extends Thread{

        
    public static void main(String[] args) {
            System.out.println(
    "Starts.");
            
    new Main("A").start();
            
    new Main("B").start();
            
    new Main("C").start();
            System.out.println(
    "End.");
        }

       
        
    public void run(){
            Singleton2 obj 
    = Singleton2.getInstance();
            System.out.println(getName()
    +": obj ="+obj);
        }

        
        
    public Main(String name){
            
    super(name);
        }

    }




    public class Singleton2 {
        
    private static Singleton2 singleton2 = null;
        
    private Singleton2(){
            System.out.println(
    "已產(chǎn)生對(duì)象實(shí)例");
            solwDown();
        }


        
    public static Singleton2 getInstance(){
            
    if(singleton2 == null){
                singleton2 
    = new Singleton2();
            }

            
    return singleton2;
        }

        
         
    private  void solwDown(){
             
    try{
                 Thread.sleep(
    1000);
             }
    catch(InterruptedException e){
                 e.printStackTrace();
             }

         }

    }


    執(zhí)行結(jié)果:

    Start.
    End.
    已產(chǎn)生對(duì)象實(shí)例.
    已產(chǎn)生對(duì)象實(shí)例.
    已產(chǎn)生對(duì)象實(shí)例.
    B: obj = Singleton2#2a9348
    C: obj = Singleton2#b91134
    A: obj = Singleton2#e343l12

    (#替換為@)

    之所以會(huì)知道這種情況是因?yàn)閕f(singleton = = null){ singleton = new Singleton2(); }判斷不夠嚴(yán)謹(jǐn)?shù)膶?dǎo)致。
    利用: singleton == null 判斷為空后去執(zhí)行new Singleton2()之前,可能會(huì)有其他線程來(lái)?yè)屜扰袛啾磉_(dá)式singleton == null,從而又執(zhí)行一遍創(chuàng)建實(shí)例的操作。

    解決辦法:
    給getInstance()方法添加Synchronized修飾符,即可修改成線程安全嚴(yán)謹(jǐn)?shù)膯卫J健?br />
    public class Singleton2 {
        
    private static Singleton2 singleton = null;

        
    private Singleton2() {
            System.out.println(
    "已產(chǎn)生對(duì)象實(shí)例");
            solwDown();
        }

        
    public static synchronized Singleton2 getInstance() {
            
    if (singleton == null) {
                singleton 
    = new Singleton2();
            }
            
    return singleton;
        }

        
    private void solwDown() {
            
    try {
                Thread.sleep(
    1000);
            } 
    catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    posted on 2007-06-08 11:36 回歸 閱讀(1217) 評(píng)論(7)  編輯  收藏 所屬分類: 個(gè)人原創(chuàng)

    Feedback

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2007-06-08 12:57 dennis
    第一個(gè)示例少了static
    public static Singleton getInstance() {
    return singleton;
    }
    也沒(méi)有考慮多線程情況下的單例模式  回復(fù)  更多評(píng)論
      

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2007-06-08 16:50 sitinspring
    多線程情況下的單例模式:

    1 public class Singleton{
    2 private static Singleton instance=null;
    3
    4 public static synchronized Singleton getInstance(){
    5 // 要用的時(shí)候再把Singleton建立起來(lái)
    6 if(instance==null){
    7 instance=new Singleton();
    8 }
    9
    10 return instance;
    11 }
    12 }


      回復(fù)  更多評(píng)論
      

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2007-06-11 09:17 一點(diǎn)思想
    第一種實(shí)行的Singleton不存在多線程隱患,累以第一次加載時(shí)候就產(chǎn)生實(shí)例.你認(rèn)為呢?  回復(fù)  更多評(píng)論
      

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2007-06-11 09:22 一點(diǎn)思想
    嗯,static寫掉了,這是一個(gè)靜態(tài)方法,直接通過(guò)類名調(diào)用  回復(fù)  更多評(píng)論
      

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2007-06-12 15:07 hardson
    synchronized 是多余的  回復(fù)  更多評(píng)論
      

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2007-06-18 14:16 想飛就飛
    第二種方式需要synchronized 的吧  回復(fù)  更多評(píng)論
      

    # re: 親密接觸設(shè)計(jì)模式(二)-------Singleton(單例) 2011-03-09 21:03 回歸
    恩,寫掉了,以后注意@一點(diǎn)思想
      回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 免费乱码中文字幕网站| 久久成人a毛片免费观看网站| 亚洲人成综合网站7777香蕉| 一区二区三区亚洲| 久久亚洲精品AB无码播放| 久久夜色精品国产亚洲 | 狠狠入ady亚洲精品| 中文日韩亚洲欧美制服| 国产精品亚洲四区在线观看 | 成人毛片免费视频| 日韩一级免费视频| 国产精品免费一级在线观看| 又粗又大又长又爽免费视频| 免费a在线观看播放| 亚洲欧洲国产成人综合在线观看| 国产精品亚洲不卡一区二区三区| 亚洲日本va在线视频观看| 国产亚洲一区二区在线观看| 亚洲狠狠综合久久| 亚洲视频一区二区在线观看| 亚洲妓女综合网99| 亚洲人AV在线无码影院观看| 爱情岛亚洲论坛在线观看| 丰满少妇作爱视频免费观看| 日批视频网址免费观看| 久久久久久久99精品免费| 亚洲w码欧洲s码免费| 好男人看视频免费2019中文| 又爽又高潮的BB视频免费看| 好看的电影网站亚洲一区| 中文字幕亚洲精品资源网| 亚洲 欧洲 日韩 综合在线| 日本亚洲欧美色视频在线播放| 久久九九久精品国产免费直播| 国产精品免费观看调教网| 免费国产作爱视频网站| 日韩免费一级毛片| 黑人大战亚洲人精品一区| 91亚洲国产成人久久精品网站| 亚洲精品无码久久久久牙蜜区| 一级大黄美女免费播放|