日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

完美的单例模式创建

發(fā)布時間:2025/3/21 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 完美的单例模式创建 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  今天把設計模式拿出來看了下,發(fā)現(xiàn)以前對于單例模式的理解很是膚淺,沒考慮線程安全,在考慮了線程安全的情況下又沒考慮性能,當然我遇到的系統(tǒng)都不怎么考慮并發(fā)性能,所以其實也無所謂,當看到單例模式的時候,上網(wǎng)搜索了下,發(fā)下一片很好的帖子,我把其中的單例模式整理了下,給了個結果出來。

  帖子地址:http://blog.csdn.net/zhangerqing/article/details/8194653

  前提都是在考慮線程安全的情況下,可以有兩種情況。分別是懶漢式和餓漢式的一種實現(xiàn)。

  1.性能不太好,每次鎖對象,當然如果你遇到的跟我遇到的系統(tǒng)都一樣不考慮性能問題,其實這么做也沒問題,但是不好。正如Oracle高級編程里面所說的那樣,你的sql能正確的完成任務,但并不代表他能很好的完成任務。

  2.我們只希望在第一次getInstance的時候去實例化對象,這個就做到了,并且線程安全,但是如果類加載的時候出問題還是有可能出問題,所以借用那篇帖子里說的,要完成完美的實現(xiàn)是不可能的,我們只能根據(jù)實際情況來選擇合適的方式。

  1.直接鎖整個對象,保證線程安全,但是由于每次獲取都會鎖對象,性能不好,也不是我們希望的。

package singlePattern;/*** Thread safe single pattern, but performance is poor, because every time we will lock the instance,* we hope lock the instance on first time but all times* * @author Administrator* */ public class SinglePattern {// private instanceprivate static SinglePattern instance = null;// private constructorprivate SinglePattern() {}// public getInstance methodpublic synchronized static SinglePattern getInstance() {if (instance == null) {instance = new SinglePattern();}return instance;} }

  2.我們需要的情形是在第一次初始化需要同步,之后的調用就不需要考慮線程同步。由于JVM在加載類的時候是互斥的,我們知道類加載器在加載類的時候會直接把靜態(tài)變量和靜態(tài)代碼塊執(zhí)行一次,然后再去去調用普通代碼快,然后去調用構造方法初始化堆,然后在返回引用賦值給棧里面的引用。于是我們可以利用類加載的靜態(tài)變量和靜態(tài)代碼塊來安全的構造單例實例。

  

package singlePattern;/*** Thread safe and performance good.* @author Administrator**/ public class UserSinglePattern {// private constructorprivate UserSinglePattern() {}// static inner class, for create a single pattern instanceprivate static class NewInstance {private static UserSinglePattern instance = new UserSinglePattern();}// the get method for single pattern instancepublic static UserSinglePattern getInstance() {return NewInstance.instance;} }

  3.如果實例采用靜態(tài)的就能實現(xiàn)在類加載的時候線程安全的初始化實例,但是卻不能實現(xiàn)lazy加載,而采用上面的靜態(tài)內部類的方式就能實現(xiàn)lazy加載,因為虛擬機機制是需要調用getInstance()方法的時候才會加載靜態(tài)內部類,如果不調用那么他是不會被加載的。下面是測試代碼,同時擁有2個靜態(tài)內部類來創(chuàng)建對象,但是只調用其中一個那么就只會加載一個,另外一個是不會被加載的。

public class SinglePatternThreadSafe {// 私有構造方法private SinglePatternThreadSafe() {System.out.println(123);}private SinglePatternThreadSafe(String str) {System.out.println(321);}// 內部類,利用類加載的互斥性來達到單例的創(chuàng)建private static class NewInstance {private static SinglePatternThreadSafe instance = new SinglePatternThreadSafe();}private static class NewInstance1 {private static SinglePatternThreadSafe in = new SinglePatternThreadSafe("11");}// 返回實例的公共方法public static SinglePatternThreadSafe getInstance() {return NewInstance.instance;}public static SinglePatternThreadSafe getInstance(String str) {return NewInstance1.in;}public static void main(String[] args) {SinglePatternThreadSafe.getInstance();}
  // 只打印出123而沒有打印11 }

再貼下我參考的地址對作者表示感謝:http://blog.csdn.net/zhangerqing/article/details/8194653

這個也寫的很好:http://www.cnblogs.com/coffee/archive/2011/12/05/inside-java-singleton.html

這篇也測試了如果在不調用靜態(tài)內部類的方法或者變量或者常量的時候內部類是不會被加載的,http://yongliang567.iteye.com/blog/904467

  

轉載于:https://www.cnblogs.com/dreamroute/p/3898433.html

總結

以上是生活随笔為你收集整理的完美的单例模式创建的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。