java23种模式之单例模式
JAVA23種設(shè)計模式四——單例模式
單例模式是一種常用的軟件設(shè)計模式,在它的核心結(jié)構(gòu)中只包含一個被稱為單例類的特殊類。通過單例模式可以保證系統(tǒng)中一個類只有一個實例而且該實例易于外界訪問,從而方便對實例個數(shù)的控制并節(jié)約系統(tǒng)資源。如果希望在系統(tǒng)中某個類的對象只能存在一個,單例模式是最好的解決方案。
什么是單例模式?
一個類有且僅有一個實例,并且自行實例化向整個系統(tǒng)提供。
也就是說,在整個程序空間中,該類只存在一個實例對象。
GoF對單例模式的定義:
保證一個類,只有一個實例存在,同時提供能對該實例加以訪問的全局訪問方法。
為什么要使用單例模式?
對于系統(tǒng)中的某些類來說,只有一個實例很重要。比如:一個系統(tǒng)中可以存在多個打印任務(wù),但是只能有一個正在工作的任務(wù);一個系統(tǒng)只能有一個窗口管理器或文件系統(tǒng);一個系統(tǒng)只能有一個計時工具或ID(序號)生成器。在多線程之間,比如servlet環(huán)境,共享一個資源或者操作同一個對象,在計算機系統(tǒng)中,線程池、緩存、日志對象、對話框、打印機、顯卡的驅(qū)動程序?qū)ο蟪1辉O(shè)計成單例模式。
單例模式的三個要點:
一是某個類只能有一個實例;
二是它必須自行創(chuàng)建這個實例;
三是它必須自行向整個系統(tǒng)提供這個實例。
具體一點就是:
一是單例模式的類只提供私有的構(gòu)造函數(shù);
二是類定義中含有一個該類的靜態(tài)私有對象;
三是該類提供了一個靜態(tài)的共有的函數(shù)用于創(chuàng)建或獲取它本身的靜態(tài)私有對象。
一般Singleton模式通常有三種形式:
第一種:餓漢式
// MainClass.java public class MainClass {public static void main(String[] args){Person per=Person.getPerson();Person per2=Person.getPerson();per.setName("張三");per2.setName("李四");System.out.println(per.getName());System.out.println(per2.getName());} } // Person.java public class Person {public static final Person person=new Person();// 保證該類里只有一個實例private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}// 構(gòu)造函數(shù)私有化private Person(){}// 提供一個全局的靜態(tài)方法public static Person getPerson(){return person;} }第二種:懶漢式
// MainClass.java public class MainClass {public static void main(String[] args){Person2 per=Person2.getPerson();Person2 per2=Person2.getPerson();per.setName("張三");per2.setName("李四");System.out.println(per.getName());System.out.println(per2.getName());} } // Person2.java public class Person2 {// 保證該類里只有一個實例private String name;// 聲明一個靜態(tài)的personprivate static Person2 person;public String getName() {return name;}public void setName(String name) {this.name = name;}// 構(gòu)造函數(shù)私有化private Person2(){}// 提供一個全局的靜態(tài)方法public static Person2 getPerson(){// 在這里需要加一個判斷,否則在主方法里會產(chǎn)生兩個不同的對象if(person==null){person=new Person2();}return person;} }結(jié)果還是:李四? ? ? ? ? ? ? ? ? 李四
在上面Person2.java代碼中,適用于單線程的情況,不適用多線程,要想適用多線程,需將相應(yīng)代碼修改為:
// 提供一個全局的靜態(tài)方法,使用同步方法public static synchronized Person2 getPerson(){// 在這里需要加一個判斷,否則在主方法里會產(chǎn)生兩個不同的對象if(person==null){person=new Person2();}return person;}這種做法又致使效率大大降低,因為每次獲取對象時,都要進(jìn)行同步!第三種:雙重檢查
// MainClass.java public class MainClass {public static void main(String[] args){Person3 per=Person3.getPerson();Person3 per2=Person3.getPerson();per.setName("張三");per2.setName("李四");System.out.println(per.getName());System.out.println(per2.getName());} } // Person3.java public class Person3 {// 保證該類里只有一個實例private String name;// 聲明一個靜態(tài)的personprivate static Person3 person;public String getName() {return name;}public void setName(String name) {this.name = name;}// 構(gòu)造函數(shù)私有化private Person3(){}// 提供一個全局的靜態(tài)方法public static Person3 getPerson(){// 雙重檢查,效率大大提高if(person==null){synchronized (Person3.class){if(person==null){person=new Person3();}}}return person;} }這種模式大大提高了執(zhí)行效率,不必每次獲取對象時都進(jìn)行同步,只是第一次需要進(jìn)行同步。
總結(jié)
以上是生活随笔為你收集整理的java23种模式之单例模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NYOJ 460 项链
- 下一篇: NYOJ 536 开心的mdd