<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)航:
     
    主站蜘蛛池模板: 99久久99这里只有免费费精品 | 久久久久久久久久国产精品免费| 无码人妻一区二区三区免费视频| 亚洲成av人片天堂网无码】| 亚洲妇女无套内射精| 亚洲色偷偷综合亚洲AV伊人蜜桃| 亚洲六月丁香婷婷综合| 日韩亚洲不卡在线视频中文字幕在线观看| 亚洲国产美女精品久久久久| 亚洲性一级理论片在线观看| 亚洲Av高清一区二区三区| 中文字幕亚洲综合小综合在线| 国产精品亚洲四区在线观看 | 亚洲中文字幕久久精品无码喷水 | 日韩激情无码免费毛片| 国产亚洲精品免费| 免费很黄很色裸乳在线观看| 亚洲精品国产精品乱码不卡| 亚洲香蕉网久久综合影视| 亚洲AV无码第一区二区三区| 91精品国产亚洲爽啪在线影院| 亚洲乱码一二三四区麻豆| 在线aⅴ亚洲中文字幕| 亚洲精品无播放器在线播放| 美女被爆羞羞网站在免费观看| 两个人的视频www免费| 91在线手机精品免费观看| 久久久久久国产a免费观看黄色大片| 成年人在线免费观看| 免费中文字幕不卡视频| 亚洲国产一二三精品无码| 亚洲精品美女在线观看| 亚洲日本va一区二区三区| 九九免费精品视频在这里| 久久免费观看国产精品| 在线免费观看一区二区三区| 亚洲成A人片在线观看无码3D | 亚洲第一福利网站在线观看| 久久亚洲综合色一区二区三区| 久久精品国产亚洲av麻豆蜜芽 | 在线观看亚洲AV日韩A∨|