單例模式

來源:互聯網
上載者:User

標籤:object   file   util   過程   執行個體   建立   put   color   spring源碼   

單例模式是一種建立性模式,是一種建立對象的方式,主要指的就是一個類在整個程式的啟動並執行過程中對象只會建立一個執行個體,就是只會被new一次,然後下次訪問這個對象的時候是不用重新建立對象的。官方的解釋是:保證一個類僅有一個執行個體,並提供一個訪問它的全域訪問點。單例模式有很多種寫法,比如:懶漢式(安全執行緒/線程不安全)、餓漢式、枚舉式、序列化式、內部類式、註冊式、註冊登記式、雙重檢查鎖(DCL)等等。

下面使用窮舉法舉幾個例子:

1.spring源碼中的單例,可以使用getBean返回不同的對象。

2.咱們程式裡面多線程同時操作一個txt檔案時會出現錯誤,這個檔案的建立可能是一個單例。

3.還有比如太陽、月亮、人等等應該也是可以說成是單例的,因為對象只有一個,所有人看到的是同一個太陽、月亮。

4.還有日常生活中的日曆。

餓漢式
package pattern.single;public class Hungry {    private Hungry(){ }    private static final Hungry hungry=new Hungry();    public static Hungry getInstance(){        return hungry;    }}
package pattern.single;public class SingleTest {    public static void main(String[] args) {       Hungry hungry=Hungry.getInstance();       Hungry hungry1=Hungry.getInstance();       System.out.println(hungry==hungry1);    }}

餓漢式的優點是效能比較高,沒有現成安全問題,還是對象在初始化的時候就已經建立,不管會不會用到都得建立,所以會有浪費資源。

懶漢式線程不安全
package pattern.single;public class LazyOne {    private LazyOne(){}    private static LazyOne lazy=null;    public static LazyOne getInstance(){        if(lazy==null){            lazy=new LazyOne();        }        return lazy;    }}
package pattern.single;public class SingleTest {    public static void main(String[] args) {        LazyOne lazyOne=LazyOne.getInstance();        System.out.println(lazyOne);     }}

這種方法只能在單線程的環境下使用,在多線程情況下存線上程安全問題,但是只會在用到的時候建立對象。

懶漢式安全執行緒
package pattern.single;public class LazyTwo {    private LazyTwo(){}    private static LazyTwo lazy=null;    public static synchronized LazyTwo getInstance(){        if(lazy==null){            lazy=new LazyTwo();        }        return lazy;    }}
package pattern.single;public class SingleTest {    public static void main(String[] args) {        LazyTwo lazyTwo=LazyTwo.getInstance();        System.out.println(lazyTwo);     }}
登記式\靜態內部類
package pattern.single;public class LazyThree {    private static boolean initialized=false;    public LazyThree(){       synchronized (LazyThree.class){          if(initialized==false){            initialized=!initialized;          }else{              throw new RuntimeException("單例被攻擊");          }       }    }    public static final LazyThree getInstance(){        return LazyHolder.Lazy;    }    private static class LazyHolder{        private final static LazyThree Lazy=new LazyThree();    }}
package pattern.single;public class SingleTest {    public static void main(String[] args) {           LazyThree lazyThree=LazyThree.getInstance();        System.out.println(lazyThree);    }}

這種方式的效率比懶漢式安全執行緒的模式更高,同時在初始化的時候也不會載入,避免了資源的浪費。

枚舉式
package pattern.single;public enum RegisterEnum {    BLOCK(){        private int r=0;        private int g=0;        private int b=0;    },RED(){        private int r=255;        private int g=0;        private int b=0;    };}
package pattern.single;public class SingleTest {    public static void main(String[] args) {        RegisterEnum registerEnum=RegisterEnum.BLOCK;        System.out.println(registerEnum);    }}
序列化式
package pattern.single;import java.io.Serializable;public class Seriable implements Serializable {    public final static Seriable INSTANCE=new Seriable();    private Seriable(){}    public static Seriable getInstance(){        return INSTANCE;    }    private Object readObject(){        return INSTANCE;    }}
package pattern.single;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class SingleTest {    public static void main(String[] args) {        Seriable s1 = null;        Seriable s2 = Seriable.getInstance();        FileOutputStream fos = null;        try {            fos = new FileOutputStream("obj");            ObjectOutputStream oos = new ObjectOutputStream(fos);            oos.writeObject(s2);            oos.flush();            oos.close();            FileInputStream fis = new FileInputStream("obj");            ObjectInputStream ois = new ObjectInputStream(fis);            s1 = (Seriable)ois.readObject();            ois.close();            System.out.println(s1);            System.out.println(s2);            System.out.println(s1 == s2);        } catch (Exception e) {            e.printStackTrace();        }    }}
註冊式
package pattern.single;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;public class BeanFactory {    private BeanFactory(){}    private static Map<String,Object> ioc=new ConcurrentHashMap<>();    public static Object getBean(String className) throws Exception {       if(ioc.containsKey(className)){           return ioc.get(className);       }else{           ioc.put(className,Class.forName(className).newInstance());       }       return ioc.get(className);    }}
package pattern.single;public class SingleTest {    public static void main(String[] args) {        Object obj=BeanFactory.getBean("xxx.yyy");
System.out.println(obj);
}
}
雙重檢查鎖(DCL)
package pattern.single;public class Singleton {    private volatile static Singleton singleton;    private Singleton(){}    public static Singleton getInstance(){        if(singleton==null){           synchronized (Singleton.class){              if(singleton==null){                 singleton=new Singleton();              }           }        }        return singleton;    }}
package pattern.single;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class SingleTest {    public static void main(String[] args) {        Object obj=Singleton.getInstance();        System.out.println(obj);    }}

這種方式採用雙鎖機制,安全且在多線程情況下能保持高效能。

 

單例模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.