170728、单例模式的三种水平代码
生活随笔
收集整理的這篇文章主要介紹了
170728、单例模式的三种水平代码
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、單例模型具備條件:
1、私有的構(gòu)造方法
2、instance(單一實例,static)和getInstance(獲取實例的方法,static)必須是static
二、下面三種不同層次單例模型代碼評價:
第一種,通過測試發(fā)現(xiàn),虛擬機加載類的時候單例就會被初始化,有些比較費時的類,我們需要使用時才加載(比如:數(shù)據(jù)庫連接,開機加速等),這時候就不太適合用這種方式
第二種,通過測試發(fā)現(xiàn)虛擬機加載類的時候不會初始化,只有調(diào)用了獲取實例的方法時才會實例化,如果已經(jīng)實例化的直接拿來用,實現(xiàn)了懶加載,但采用了synchronized同步的方式,性能會有所下降
第三種,通過測試發(fā)現(xiàn),實現(xiàn)了懶加載的功能(靜態(tài)內(nèi)部類),也解決了第二種性能下降的問題。其實代理模型等也是可以實現(xiàn)的
三、總結(jié):我們可以通過優(yōu)化代碼來實現(xiàn)性能最佳的單例模型類。推薦使用第三種方式,如果不是很費時的單例第一種也沒關(guān)系。今天不舉spring或jdk單例模型的實現(xiàn),因為單例很好理解。值得注意的是,通過反射強制訪問等,可能會破壞單例,但是是有辦法避免的,后面有機會再做介紹。
四、單例模型未優(yōu)化的例子(原始)
public class Singleton {//staticprivate static Singleton instance = new Singleton();//私有構(gòu)造方法private Singleton() {}//staticpublic static Singleton getInstance() {return instance;}
}
五、下面是三種不同水平的單例代碼(第三種性能最佳)
1)第一種:(上例及下面這個例子分析),虛擬機加載的時候就會初始化
public class SingletonObject {private static SingletonObject instance = new SingletonObject();private SingletonObject() {System.out.println("SingletonObject is created");}public static SingletonObject getInstance() {return instance;}//單獨調(diào)用此方法(SingletonObject.otherMethod())時,”SingletonObject is created“也會被打印,說明虛擬機加載的時候就會初始化public static void otherMethod() {System.out.println("this is other method");}
}
2)第二種:使用synchronized同步,虛擬機加載的時候不初始化,調(diào)用getInstance方法時才初始化 public class LazilySingletonObject {private static LazilySingletonObject instance = null;private LazilySingletonObject() {System.out.println("LazilySingletonObject is created");}/** 這里必須同步鎖synchronized*/public static synchronized LazilySingletonObject getInstance() {if (null == instance) {instance = new LazilySingletonObject();}return instance;}//單獨調(diào)用此方法(LazilySingletonObject.otherMethod())時,"LazilySingletonObject is created"不會被答應(yīng),說明單例沒有實例化public static void otherMethod() {System.out.println("this is other method");} }
3)第三種:使用靜態(tài)內(nèi)部類實現(xiàn)賴加載,不使用synchronized,這樣可以優(yōu)化性能 public class OptimizedLazilySingletonObject {private OptimizedLazilySingletonObject() {System.out.println("OptimizedLazilySingletonObject is created");}//靜態(tài)內(nèi)部類中持有這個對象private static class SingletonHolder {private static OptimizedLazilySingletonObject instance = new OptimizedLazilySingletonObject();}public static OptimizedLazilySingletonObject getInstance() {return SingletonHolder.instance;}}六、測試 public class SingletonTest {public static void main(String[] args) {/*** 輸出:Singleton is created* 說明獲取對象的時候私有方法需要調(diào)用(很好理解)*///Singleton.getInstance();/*** 輸出:SingletonObject is created* this is other method* 說明:即使調(diào)用這個類中的其他方法,類也會立即初始化* 如果對于那種非常費時的初始化我們希望是用的時候才初始化(比如數(shù)據(jù)庫連接等)*/SingletonObject.otherMethod();/*** 實現(xiàn)了賴加載,使用的時候才初始化,但是使用同步鎖,性能會下降*///LazilySingletonObject.getInstance();/*** 輸出:this is other method* 說明:不用的時候,單例不會初始化*/LazilySingletonObject.otherMethod();/*** 實現(xiàn)了賴加載,并沒有影響性能*/OptimizedLazilySingletonObject.getInstance();}}
2)第二種:使用synchronized同步,虛擬機加載的時候不初始化,調(diào)用getInstance方法時才初始化 public class LazilySingletonObject {private static LazilySingletonObject instance = null;private LazilySingletonObject() {System.out.println("LazilySingletonObject is created");}/** 這里必須同步鎖synchronized*/public static synchronized LazilySingletonObject getInstance() {if (null == instance) {instance = new LazilySingletonObject();}return instance;}//單獨調(diào)用此方法(LazilySingletonObject.otherMethod())時,"LazilySingletonObject is created"不會被答應(yīng),說明單例沒有實例化public static void otherMethod() {System.out.println("this is other method");} }
3)第三種:使用靜態(tài)內(nèi)部類實現(xiàn)賴加載,不使用synchronized,這樣可以優(yōu)化性能 public class OptimizedLazilySingletonObject {private OptimizedLazilySingletonObject() {System.out.println("OptimizedLazilySingletonObject is created");}//靜態(tài)內(nèi)部類中持有這個對象private static class SingletonHolder {private static OptimizedLazilySingletonObject instance = new OptimizedLazilySingletonObject();}public static OptimizedLazilySingletonObject getInstance() {return SingletonHolder.instance;}}六、測試 public class SingletonTest {public static void main(String[] args) {/*** 輸出:Singleton is created* 說明獲取對象的時候私有方法需要調(diào)用(很好理解)*///Singleton.getInstance();/*** 輸出:SingletonObject is created* this is other method* 說明:即使調(diào)用這個類中的其他方法,類也會立即初始化* 如果對于那種非常費時的初始化我們希望是用的時候才初始化(比如數(shù)據(jù)庫連接等)*/SingletonObject.otherMethod();/*** 實現(xiàn)了賴加載,使用的時候才初始化,但是使用同步鎖,性能會下降*///LazilySingletonObject.getInstance();/*** 輸出:this is other method* 說明:不用的時候,單例不會初始化*/LazilySingletonObject.otherMethod();/*** 實現(xiàn)了賴加載,并沒有影響性能*/OptimizedLazilySingletonObject.getInstance();}}
?
轉(zhuǎn)載于:https://www.cnblogs.com/zrbfree/p/7484686.html
總結(jié)
以上是生活随笔為你收集整理的170728、单例模式的三种水平代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hook技术简介
- 下一篇: linux 下脚本查看带宽 (不需要安装