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

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

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

    beauty_beast

    上善若水 厚德載物
    本文只是本人的學(xué)習(xí)總結(jié),目的希望能和大家一起交流分享,順便備忘,如有不正確的地方,歡迎指正。

    singleton模式我們?cè)陂_發(fā)時(shí)經(jīng)常會(huì)使用到,比如將一個(gè)系統(tǒng)運(yùn)行時(shí)的初始配置數(shù)據(jù)封裝成一個(gè)配置對(duì)象,在系統(tǒng)初始化時(shí)實(shí)例化該對(duì)象,因?yàn)閷?duì)于整個(gè)系統(tǒng)運(yùn)行時(shí)該對(duì)象的成員都是不變的,如果只需要一個(gè)實(shí)例就行,這樣對(duì)系統(tǒng)的性能是很有益的。往往該配置對(duì)象都是和資源密切相關(guān)的(例如 數(shù)據(jù)庫連接、文件等等),但是如果采用該模式設(shè)計(jì)、編碼不當(dāng),常會(huì)造成資源泄漏,甚至更嚴(yán)重的問題(我的最近一個(gè)項(xiàng)目就出現(xiàn)過問題)。
    一個(gè)簡(jiǎn)單的單實(shí)例模式實(shí)現(xiàn)如下:
    /*
     * Created on 2005-8-18
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */

    package study.design.singleton;



    /**
     * @author liusuifeng
     * 
     * TODO To change the template for this generated type comment go to Window -
     * Preferences - Java - Code Style - Code Templates
     
    */

    public class TestSingleTon   {
        
    private static TestSingleTon test = null;

        
    private TestSingleTon() {

            System.
    out.println("contructor has been inited");
        }


        
    public static synchronized TestSingleTon getInstance() {
            
    if (test == null{

                test 
    = new TestSingleTon();

            }

            
    return test;
        }


    }


    這樣的定義在單線程應(yīng)用中時(shí)沒有問題的,但是如果是多線程訪問的話實(shí)際就不是單實(shí)例了:
    舉個(gè)簡(jiǎn)單例子:

    /*
     * Created on 2005-8-18
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */
    package study.design.singleton;

    /**
     * @author liusuifeng
     
     
    */
    public class TestThread extends Thread {
        
    public void run(){
            TestSingleTon test
    =TestSingleTon.getInstance();        
            System.
    out.println("TestSingleTon===="+test);
            
        }
        
        
    public static void main(String[] args){
            
    for(int i=0;i<10;i++){
                TestThread mthread
    =new TestThread();                
                mthread.start();
            }        
        }
        
        
    }


    運(yùn)行時(shí)系統(tǒng)輸出如下:
    TestSingleTon====study.design.singleton.TestSingleTon@107077e
    TestSingleTon====study.design.singleton.TestSingleTon@7ced01
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8
    TestSingleTon====study.design.singleton.TestSingleTon@1ac04e8

    呵呵,單實(shí)例變成三實(shí)例了,所以我們編碼、設(shè)計(jì)時(shí)一定要考慮該對(duì)象的調(diào)用環(huán)境,保險(xiǎn)起見,我們可以加上同步,修改原來的實(shí)現(xiàn),將方法加上同步:
    public static synchronized TestSingleTon getInstance() {
            
    if (test == null{

                test 
    = new TestSingleTon();

            }

            
    return test;
        }

    執(zhí)行測(cè)試代碼輸出:
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a
    TestSingleTon====study.design.singleton.TestSingleTon@11a698a

    這樣就保證了多線程調(diào)用時(shí)也只有一個(gè)實(shí)例。
    呵呵,這樣就能保證在同一虛擬機(jī)上只有一個(gè)實(shí)例了嗎?
    如果對(duì)象是個(gè)可序列化的對(duì)象呢?
    /*
     * Created on 2005-8-18
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */
    package study.design.singleton;


    import java.io.Serializable;

    /**
     * @author liusuifeng
     * 
     * TODO To change the template for this generated type comment go to Window -
     * Preferences - Java - Code Style - Code Templates
     
    */
    public class TestSingleTon implements Serializable {
        
    private static TestSingleTon test = null;

        
    private TestSingleTon() {

            System.
    out.println("contructor has been inited");
        }

        
    public static synchronized TestSingleTon getInstance() {
            
    if (test == null) {

                test 
    = new TestSingleTon();

            }
            
    return test;
        }

    }

    下面的方法就又偷出一個(gè)實(shí)例出來:
    /*
     * Created on 2005-8-18
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     
    */
    package study.design.singleton;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;

    /**
     * @author liusuifeng
     * 
     * TODO To change the template for this generated type comment go to Window -
     * Preferences - Java - Code Style - Code Templates
     
    */
    public class TestSerialObject {
        
        
    private void writeObject() {
            TestSingleTon tempobj 
    = TestSingleTon.getInstance();
            ObjectOutputStream oos
    =null;
            
    try {
                oos 
    = new ObjectOutputStream(
                        
    new FileOutputStream("c:\\object.data"));
                oos.writeObject(tempobj);
            } 
    catch (FileNotFoundException e1) {
                
                e1.printStackTrace();
            } 
    catch (IOException e1) {            
                e1.printStackTrace();
            }
            
    finally{
                
    try {
                    oos.close();
                } 
    catch (IOException e) {
                    
                    e.printStackTrace();
                }
            }

        }

        
    public Object getSerialObject() {
            Object o 
    = new Object();
            ObjectInputStream ois 
    =null;
            writeObject();
            
    try {
                 ois 
    = new ObjectInputStream(new FileInputStream(
                        
    "c:\\object.data"));
                 o
    =ois.readObject();
                
            } 
    catch (FileNotFoundException e) {            
                e.printStackTrace();
            } 
    catch (IOException e) {
                
                e.printStackTrace();
            } 
    catch (ClassNotFoundException e) {
                
                e.printStackTrace();
            }
            
    finally{
                
    try {
                    ois.close();
                } 
    catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            
    return o;
        }

        
    public static void main(String[] args) {
            TestSerialObject to
    =new TestSerialObject();            
            Object obj1
    =to.getSerialObject();
            System.
    out.println(obj1.equals(TestSingleTon.getInstance()));
        }
    }

    運(yùn)行輸出如下:
    contructor has been inited
    false

    學(xué)習(xí)總結(jié)如下:
        采用單實(shí)例模式時(shí)設(shè)計(jì)編碼時(shí)要盡可能的多考慮其調(diào)用場(chǎng)景,在實(shí)現(xiàn)中規(guī)避不應(yīng)該出現(xiàn)的多實(shí)例情形。














    Feedback

    # re: 學(xué)習(xí)設(shè)計(jì)模式之singleton模式  回復(fù)  更多評(píng)論   

    2005-08-18 22:03 by Rocky
    呵呵,我再補(bǔ)充一點(diǎn),關(guān)于單實(shí)例。

    版主例子中給了單實(shí)例的一種實(shí)現(xiàn):
    public class TestClass
    {
    private static TestClass instance;
    private TestClass(){}

    public static TestClass()
    {
    if( null != instance) instance = new TestClass();
    return instance;
    }
    public void testA(){};
    public void testB(){};
    }

    這種是比較常用的,但有這么一個(gè)問題。即該類一旦實(shí)例化,那么將永遠(yuǎn)不能被回收。即使你將 instance 賦成 null,也不能將該類清除掉。


    還有一種單實(shí)例模式,見下:
    public class TestClass
    {
    private String aaa;
    public TestClass(){
    //初始化單實(shí)例中的一些變量
    aaa = .....;
    }

    public static void testA(){
    //針對(duì)aaa的操作
    }

    public static void testB(){}{
    //針對(duì)aaa的操作
    }
    }
    即將方法聲明為 static 方法。這樣聲明之后,那么針對(duì)aaa的操作的所有行為也將遵循單實(shí)例模式。

    這種方式的優(yōu)點(diǎn)就是類的實(shí)例可以隨時(shí)銷毀。但有個(gè)缺點(diǎn):即每次調(diào)用都需要?jiǎng)?chuàng)建一個(gè)實(shí)例出來,有時(shí)間上的開銷。

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 成人久久免费网站| 97在线线免费观看视频在线观看| 国产亚洲成av片在线观看| 最近中文字幕mv免费高清在线| 色在线亚洲视频www| 免费人成在线观看网站品爱网日本| 在线观看免费黄网站| 亚洲字幕在线观看| 亚洲av无码乱码在线观看野外| 毛片在线播放免费观看| 一本色道久久88—综合亚洲精品 | 男女作爱免费网站| 在线观看亚洲人成网站| 午夜亚洲av永久无码精品| 蜜桃视频在线观看免费视频网站WWW| 亚洲精华国产精华精华液好用 | 亚洲国产高清美女在线观看| 国产亚洲精品免费| 四虎在线成人免费网站| 深夜免费在线视频| 亚洲国产成人精品激情| 亚洲线精品一区二区三区影音先锋 | 国产一级特黄高清免费大片| 午夜免费福利片观看| 美女啪啪网站又黄又免费| 久久精品国产亚洲AV嫖农村妇女| 免费国产不卡午夜福在线| 国产成人精品免费视频动漫| 中文字字幕在线高清免费电影| 国产亚洲玖玖玖在线观看| 亚洲VA中文字幕无码毛片 | 亚洲最大免费视频网| 国产日产亚洲系列| 真实乱视频国产免费观看| 免费人成在线观看69式小视频| a在线观看免费视频| 黄网站在线播放视频免费观看| 波多野结衣亚洲一级| 亚洲精品国产啊女成拍色拍| 国精无码欧精品亚洲一区| 亚洲国产成人五月综合网 |