1. 程式人生 > >Java中用單例模式有什麼好處

Java中用單例模式有什麼好處

Java Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個例項存在。 使用Singleton的好處還在於可以節省記憶體,因為它限制了例項的個數,有利於Java垃圾回收(garbage collection)。

我們在瀏覽BBS、SNS網站的時候,常常會看到“當前線上人數”這樣的一項內容。對於這樣的一項功能,我們通常的做法是把當前的線上人數存放到一個記憶體、檔案或者資料庫中,每次使用者登入的時候,就會馬上從記憶體、檔案或者資料庫中取出,在其基礎上加1後,作為當前的線上人數進行顯示,然後再把它儲存回記憶體、檔案或者資料庫裡,這樣後續登入的使用者看到的就是更新後的當前線上人數;同樣的道理,當用戶退出後,當前線上人數進行減1的工作。所以,對於這樣的一個需求,我們按照面向物件的設計思想,可以把它抽象為“線上計數器”這樣一個物件。

網站程式碼中凡是用到計數器的地方,只要new一個計數器物件,然後就可以獲取、儲存、增加或者減少線上人數的數量。不過,我們的程式碼實際的使用效果並不好。假如有多個使用者同時登入,那麼在這個時刻,通過計數器取到的線上人數是相同的,於是他們使用各自的計數器加1後存入檔案或者資料庫。這樣操作後續登陸的使用者得到的線上人數,與實際的線上人數並不一致。所以,把這個計數器設計為一個全域性物件,所有人都共用同一份資料,就可以避免類似的問題,這就是我們所說的單例模式的其中的一種應用。

單例模式能夠保證一個類僅有唯一的例項,並提供一個全域性訪問點。

我們是不是可以通過一個全域性變數來實現單例模式的要求呢?我們只要仔細地想想看,全域性變數確實可以提供一個全域性訪問點,但是它不能防止別人例項化多個物件。通過外部程式來控制的物件的產生的個數,勢必會系統的增加管理成本,增大模組之間的耦合度。所以,最好的解決辦法就是讓類自己負責儲存它的唯一例項,並且讓這個類保證不會產生第二個例項,同時提供一個讓外部物件訪問該例項的方法。自己的事情自己辦,而不是由別人代辦,這非常符合面向物件的封裝原則。

單例模式主要有3個特點,:

1、單例類確保自己只有一個例項。

2、單例類必須自己建立自己的例項。

3、單例類必須為其他物件提供唯一的例項。

單例模式的實現方式:懶漢單例類和餓漢單例類

單例模式的實現有多種方法,常見的就有懶漢式單例類和餓漢式單例類。我們前面介紹的實現方法就屬於懶漢式單例類。

· 懶漢式單例類

對於懶漢模式,我們可以這樣理解:該單例類非常懶,只有在自身需要的時候才會行動,從來不知道及早做好準備。它在需要物件的時候,才判斷是否已有物件,如果沒有就立即建立一個物件,然後返回,如果已有物件就不再建立,立即返回。

懶漢模式只在外部物件第一次請求例項的時候才去建立。

· 餓漢式單例

對於餓漢模式,我們可以這樣理解:該單例類非常餓,迫切需要吃東西,所以它在類載入的時候就立即建立物件。

我們對比一下懶漢模式和餓漢模式的優缺點:

懶漢模式,它的特點是執行時獲得物件的速度比較慢,但載入類的時候比較快。它在整個應用的生命週期只有一部分時間在佔用資源。

餓漢模式,它的特點是載入類的時候比較慢,但執行時獲得物件的速度比較快。它從載入到應用結束會一直佔用資源。

這兩種模式對於初始化較快,佔用資源少的輕量級物件來說,沒有多大的效能差異,選擇懶漢式還是餓漢式都沒有問題。但是對於初始化慢,佔用資源多的重量級物件來說,就會有比較明顯的差別了。所以,對重量級物件應用餓漢模式,類載入時速度慢,但執行時速度快;懶漢模式則與之相反,類載入時速度快,但執行時第一次獲得物件的速度慢。

從使用者體驗的角度來說,我們應該首選餓漢模式。我們願意等待某個程式花較長的時間初始化,卻不喜歡在程式執行時等待太久,給人一種反應遲鈍的感覺,所以對於有重量級物件參與的單例模式,我們推薦使用餓漢模式。

而對於初始化較快的輕量級物件來說,選用哪種方法都可以。如果一個應用中使用了大量單例模式,我們就應該權衡兩種方法了。輕量級物件的單例採用懶漢模式,減輕載入時的負擔,縮短載入時間,提高載入效率;同時由於是輕量級物件,把這些物件的建立放在使用時進行,實際就是把建立單例物件所消耗的時間分攤到整個應用中去了,對於整個應用的執行效率沒有太大影響。

什麼情況下使用單例模式

單例模式也是一種比較常見的設計模式,它到底能帶給我們什麼好處呢?其實無非是三個方面的作用:

第一、控制資源的使用,通過執行緒同步來控制資源的併發訪問;

第二、控制例項產生的數量,達到節約資源的目的。

第三、作為通訊媒介使用,也就是資料共享,它可以在不建立直接關聯的條件下,讓多個不相關的兩個執行緒或者程序之間實現通訊。

比如,資料庫連線池的設計一般採用單例模式,資料庫連線是一種資料庫資源。軟體系統中使用資料庫連線池,主要是節省開啟或者關閉資料庫連線所引起的效率損耗,這種效率上的損耗還是非常昂貴的。當然,使用資料庫連線池還有很多其它的好處,可以遮蔽不同資料資料庫之間的差異,實現系統對資料庫的低度耦合,也可以被多個系統同時使用,具有高可複用性,還能方便對資料庫連線的管理等等。資料庫連線池屬於重量級資源,一個應用中只需要保留一份即可,既節省了資源又方便管理。所以資料庫連線池採用單例模式進行設計會是一個非常好的選擇。

在我們日常使用的在Windows中也有不少單例模式設計的元件,象常用的檔案管理器。由於Windows作業系統是一個典型的多程序多執行緒系統,那麼在建立或者刪除某個檔案的時候,就不可避免地出現多個程序或執行緒同時操作一個檔案的現象。採用單例模式設計的檔案管理器就可以完美的解決這個問題,所有的檔案操作都必須通過唯一的例項進行,這樣就不會產生混亂的現象。

再比如,每臺計算機可以有若干個印表機,如果每一個程序或者執行緒都獨立地使用印表機資源的話,那麼我們打印出來的結果就有可能既包含這個列印任務的一部分,又包含另外一個列印任務的一部分。所以,大多數的作業系統最終為列印任務設計了一個單例模式的假離線服務Printer Spooler,所有的列印任務都需要通過假離線服務進行。

實際上,配置資訊類、管理類、控制類、門面類、代理類通常被設計為單例類。像Java的Struts、spring框架,.Net的Spring.NET框架,以及PHP的Zend框架都大量使用了單例模式。

詳細內容請參考:

使用單例模式最核心的一點是體現了面向物件封裝特性中的“單一職責”和“物件自治”原則。

很多時候我們要保證類的例項只有一個。我們可能在自己的程式碼中判斷需要的類的例項有無,無就new一個。這樣看似不錯。問題是,你用到這個類的地方有n個,這樣你就需要n個判斷。為什麼不把這個職責交給類本身呢?然後讓類提供一個介面訪問
以上引自:http://blog.csdn.net/ljhljh8888/article/details/8017701
最後附上兩種單例模式的java程式碼:

懶漢式:
public class SingletonClass{
    private static SingletonClass instance=null;
    public static synchronized SingletonClass getInstance(){
        if(instance==null){
               instance=new SingletonClass();
        }
        return instance;
    }
    private SingletonClass(){
    }
}
餓漢式:
public class Singleton{
    //在自己內部定義自己的一個例項,只供內部呼叫
    private static final Singleton instance = new Singleton();
    private Singleton(){
        //do something
    }
    //這裡提供了一個供外部訪問本class的靜態方法,可以直接訪問
    public static Singleton getInstance(){
        return instance;
    }
}

其中我們注意到,懶漢單例模式中getInstance方法有一個synchronized關鍵字,該關鍵字作用為當多個執行緒同時訪問該方法的時候,必須等一個執行緒訪問完,才能進行訪問,這就預防了多個執行緒同時訪問而建立多個例項。餓漢單例模式中instance屬性被添加了final關鍵字,這就確保了該例項是個常量,不允許修改。

相關推薦

【轉】Java中用模式什麽好處

別了 通過 詳細 線程同步 請求 占用 解決辦法 每次 耦合 Java Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。 使用Singleton的好處還在於可以節省內存,因為它限制了實例的個數,有利於Java垃圾回收(garb

Java中用模式什麼好處

Java Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個例項存在。 使用Singleton的好處還在於可以節省記憶體,因為它限制了例項的個數,有利於Java垃圾回收(garbage collection)。 我們在瀏覽BBS

Java模式——C++基礎的Java入門(五)

目錄 什麼是單例模式(Singleton)? 一、 懶漢模式 1、 例項 2、 原理 二、 餓漢模式 1、 例項 什麼是單例模式(Singleton)? 設計模式:Java中,一共有23種設計模式,說白了就是比較牛的程式碼設計思想。單例模式裡面非常簡單的一種。

溫故而知新(java實現)模式的七種寫法

反序 防止 代碼 工作 html 我想 變種 evel 才會 第一種(懶漢,線程不安全): Java代碼 public class Singleton { private static Singleton instance; private S

Java模式的七種寫法

work 為我 get 加載 java dev 創建 一個 對象 轉載出處:http://cantellow.javaeye.com/blog/838473 第一種(懶漢,線程不安全): 1 public class Singleton { 2 private

ElasticSearch java api -模式

elastic earch request index mmu parse .get 單例 list數據 //單例模式 private static Settings getSettingInstance(){ if(settings==null){ synchron

Java模式(singleton)

ron 好聽 on() == sin 如果 odin 如同 可能 為什麽需要單例?只因為國家的獨生子女政策(當然現在可以生2個) 單例是一個很孤獨的物種,因為它的類裏面做多只有也僅只有它一個。 常見的是懶漢及餓漢模式, 1.懶漢,為什麽這麽叫,看看英文,原為lazy loa

Java模式實現

java 單例模式 只能生成一個實例的類是實現了Singleton(單例)模式的類。以下為C#實現單例模式的方式方式一只使用於單線程環境// 把構造函數設為私有函數以禁止他人創建實例 // 定義一個靜態的實例,在需要的時候創建該實例 // 在Singleton的靜態屬性Instance中,只有

Java基礎 模式之懶漢式

懶漢 私有 珍惜 src pac auth 如果 x64 version 禮悟: 好好學習多思考,尊師重道存感恩。葉見尋根三返一,活水清源藏於零。 虛懷若谷良心主,皓月當空自在王。願給最苦行無悔,誠勸且行且珍惜。 os :

Java基礎---模式 觀察者模式 反射 工廠模式

package cn.itcast.single; /*  單例設計模式:     懶漢單例設計模式(執行緒安全問題 的解決方案):   步驟:   1. 私有化建構函式。   2. 宣告

Java學習——模式

單例模式 特點:一個類只允許產生一個例項化物件 一個普通的類我們可以new出多個例項化物件,如何才能限制物件的個數呢? 產生物件的本質是我們呼叫了類的構造方法,如果我們無法呼叫構造方法不就不會產生例項化物件了嗎?最容易想到的就是將類的構造方法私有化。一旦構造方法被私有化了,表示外部無

java模式:餓漢式、懶漢式、雙重校驗鎖、列舉、靜態內部類

一、餓漢式: /** * 餓漢式: * 不存在多執行緒同步問題,當類被載入時,初始化並分配記憶體空間; * 當類被解除安裝時,才釋放所佔記憶體,因此在某些特定條件下會耗費記憶體。 * * @author: Rodge * @time: 2018年10月4日 下午4:35:12 * @

java基礎-模式

java中的定義: 單例模式( Singleton模式),一個類有且僅有一個例項,並且自行例項化向整個系統提供(公開)。 單例模式的三個要點 具體實現的角度來說: 構造方法私有化 靜態屬性指向例項 public static的getInstance方法,返

【第11天】Java模式、介面以及Object類常用的方法

1 單例模式 1.1 醉漢式 1.2 懶漢式 2 介面(interface) 3 Object類常用的方法 3.1 clone() 3.2 finalize()

java】——模式學習理解

    單例模式,總而言之還是多種多樣的,理解不同的單例模式,對於開發過程中更是極為方便,以下彙總幾種單例的使用,積累備用。     一、只適合單執行緒環境 package test; /** * @author xiao

java模式

單例模式屬於設計模式中的一種,使用單例模式的類允許只存在一個物件例項。在java開發中,有好多種不同單例模式的寫法,而且運用的場景也各不相同,因此在java面試中屬於高頻考點,面試官會讓面試者手寫單例模式程式碼,所以提醒大家特別注意下。 這裡我就記錄下常見的幾種單例模式寫法:

什麼是模式模式什麼作用?為什麼要用模式

單例模式 單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。 這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種訪問其唯一的物

java模式,為什麼需要volatile及靜態內部類

目前看了java併發的書,記錄一下。對於java的單例模式,正確的程式碼應該為: public class TestInstance { private volatile static TestInstance instance; public st

孔乙己的疑問:模式幾種寫法

引子 單例模式的文章可以說是百家爭鳴,今天我也來說道說道,大家共同提升。 單例模式的作用和使用場景 單例模式(Singleton Pattern) 確保某一個類只有一個例項,而且可以自行例項化並向整個系統提供這個例項,這個類稱為單例類,它提供全域性訪問的方法。 單例模式是一種物件建立型模式。 使用場

Java-singleton模式

單執行緒懶漢式 註解:Singleton的靜態屬性instance中,只有instance為null的時候才建立一個例項,建構函式私有,確保每次都只建立一個,避免重複建立。 缺點:只在單執行緒的情況下正常執行,在多執行緒的情況下,就會出問題。例如:當兩個執行緒同時執行到判斷insta