本文目錄一覽:
- 1、在Java中,單例設計模式是什麼意思?有什麼優勢?
- 2、java開發在什麼情況下使用單例模式?
- 3、JAVA單例模式有哪些?
- 4、在java開發中,為什麼要使用單例模式?
- 5、設計模式之單例模式
- 6、Java單例模式是什麼意思?
在Java中,單例設計模式是什麼意思?有什麼優勢?
單例模式:保證一個類在使用過程中,只有一個實例。
優勢就是單例模式的作用,這個類永遠只有一個實例。
還在於可以節省內存,因為它限制了實例的個數,有利於Java垃圾回收。
java的學習建議:
首先要看書讀理論,不一定都懂,因為有一個懂的過程;
然後就是分析代碼,看看書上的代碼的意思,逐行逐行地看,去體會;
最重要的一點就是敲寫代碼,剛開始不會沒關係,照着書一行一行的敲,然後運行,觀察結果,把程序運行結果聯繫程序代碼,學得多一點了就嘗試修改代碼,改一點點看運行結果有什麼變化,便於理解程序內部執行的機制。
java開發在什麼情況下使用單例模式?
使用原則如下:
1.單例模式:確保一個類只有一個實例,自行實例化並向系統提供這個實例
2.單例模式分類:餓單例模式(類加載時實例化一個對象給自己的引用),懶單例模式(調用取得實例的方法如getInstance時才會實例化對象)(java中餓單例模式性能優於懶單例模式,c++中一般使用懶單例模式)
單例模式(Singleton),也叫單子模式,是一種常用的軟件設計模式。在應用這個模式時,單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行為。
比如在某個服務器程序中,該服務器的配置信息存放在一個文件中,這些配置數據由一個單例對象統一讀取,然後服務進程中的其他對象再通過這個單例對象獲取這些配置信息。這種方式簡化了在複雜環境下的配置管理。
JAVA單例模式有哪些?
一、懶漢式單例\x0d\x0a在類加載的時候不創建單例實例。只有在第一次請求實例的時候的時候創建,並且只在第一次創建後,以後不再創建該類的實例。\x0d\x0a \x0d\x0apublic class LazySingleton {\x0d\x0a /**\x0d\x0a * 私有靜態對象,加載時候不做初始化\x0d\x0a */\x0d\x0a private static LazySingleton m_intance=null;\x0d\x0a /**\x0d\x0a * 私有構造方法,避免外部創建實例\x0d\x0a */\x0d\x0a private LazySingleton(){\x0d\x0a }\x0d\x0a /**\x0d\x0a * 靜態工廠方法,返回此類的唯一實例. \x0d\x0a * 當發現實例沒有初始化的時候,才初始化.\x0d\x0a */\x0d\x0a synchronized public static LazySingleton getInstance(){\x0d\x0a if(m_intance==null){\x0d\x0a m_intance=new LazySingleton();\x0d\x0a }\x0d\x0a return m_intance;\x0d\x0a }\x0d\x0a}\x0d\x0a\x0d\x0a二、餓漢式單例\x0d\x0a在類被加載的時候,唯一實例已經被創建。\x0d\x0a \x0d\x0apublic class EagerSingleton {\x0d\x0a /**\x0d\x0a * 私有的(private)唯一(static final)實例成員,在類加載的時候就創建好了單例對象\x0d\x0a */\x0d\x0a private static final EagerSingleton m_instance = new EagerSingleton();\x0d\x0a /**\x0d\x0a * 私有構造方法,避免外部創建實例\x0d\x0a */\x0d\x0a private EagerSingleton() {\x0d\x0a }\x0d\x0a /**\x0d\x0a * 靜態工廠方法,返回此類的唯一實例.\x0d\x0a * @return EagerSingleton\x0d\x0a */\x0d\x0a public static EagerSingleton getInstance() {\x0d\x0a return m_instance;\x0d\x0a }\x0d\x0a}\x0d\x0a \x0d\x0a************************************************************************************** 懶漢方式,指全局的單例實例在第一次被使用時構建; \x0d\x0a餓漢方式,指全局的單例實例在類裝載時構建 \x0d\x0a**************************************************************************************\x0d\x0a\x0d\x0a三、登記式單例\x0d\x0a這個單例實際上維護的是一組單例類的實例,將這些實例存放在一個Map(登記薄)中,對於已經登記過的實例,則從工廠直接返回,對於沒有登記的,則先登記,而後返回。\x0d\x0apublic class RegSingleton {\x0d\x0a /**\x0d\x0a * 登記薄,用來存放所有登記的實例\x0d\x0a */\x0d\x0a private static Map m_registry = new HashMap();\x0d\x0a //在類加載的時候添加一個實例到登記薄\x0d\x0a static {\x0d\x0a RegSingleton x = new RegSingleton();\x0d\x0a m_registry.put(x.getClass().getName(), x);\x0d\x0a }\x0d\x0a /**\x0d\x0a * 受保護的默認構造方法\x0d\x0a */\x0d\x0a protected RegSingleton() {\x0d\x0a }\x0d\x0a /**\x0d\x0a * 靜態工廠方法,返回指定登記對象的唯一實例;\x0d\x0a * 對於已登記的直接取出返回,對於還未登記的,先登記,然後取出返回\x0d\x0a * @param name\x0d\x0a * @return RegSingleton\x0d\x0a */\x0d\x0a public static RegSingleton getInstance(String name) {\x0d\x0a if (name == null) {\x0d\x0a name = “RegSingleton”;\x0d\x0a }\x0d\x0a if (m_registry.get(name) == null) {\x0d\x0a try {\x0d\x0a m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());\x0d\x0a } catch (InstantiationException e) {\x0d\x0a e.printStackTrace();\x0d\x0a } catch (IllegalAccessException e) {\x0d\x0a e.printStackTrace();\x0d\x0a } catch (ClassNotFoundException e) {\x0d\x0a e.printStackTrace();\x0d\x0a }\x0d\x0a }\x0d\x0a return m_registry.get(name);\x0d\x0a }\x0d\x0a /**\x0d\x0a * 一個示意性的商業方法\x0d\x0a * @return String\x0d\x0a */\x0d\x0a public String about() {\x0d\x0a return “Hello,I am RegSingleton!”;\x0d\x0a }\x0d\x0a}
在java開發中,為什麼要使用單例模式?
java單例模式確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例。
特點:
一個類只能有一個實例;
自己創建這個實例;
整個系統都要使用這個實例。
Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄 數據庫連接都需要這樣的單線程操作。一些資源管理器常常設計成單例模式。
外部資源:譬如每台計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中。每台計算機可以有若干個通信端口,系統應當集中管理這些通信端口,以避免一個通信端口被兩個請求同時調用。
內部資源,譬如,大多數的軟件都有一個(甚至多個)屬性文件存放系統配置。這樣的系統應當由一個對象來管理這些屬性文件。
單例模式,能避免實例重複創建;
單例模式,應用於避免存在多個實例引起程序邏輯錯誤的場合;
單例模式,較節約內存。
設計模式之單例模式
本文開始整個設計模式的系列學習,希望通過不斷的學習,可以對設計模式有整體的掌握,並在項目中根據實際的情況加以利用。
單例模式是指一個類僅允許創建其自身的一個實例,並提供對該實例的訪問權限。它包含靜態變量,可以容納其自身的唯一和私有實例。它被應用於這種場景——用戶希望類的實例被約束為一個對象。在需要單個對象來協調整個系統時,它會很有幫助。
1、單例類只能有一個實例
2、單例類必須自己創建自己的唯一實例
3、單例類必須給其他所有對象提供這一實例
1.盡量使用懶加載
2.雙重檢索實現線程安全
3.構造方法為private
4.定義靜態的Singleton instance對象和getInstance()方法
單例模式至少有六種寫法。
作為一種重要的設計模式,單例模式的好處有:
1、控制資源的使用,通過線程同步來控制資源的並發訪問
2、控制實例的產生,以達到節約資源的目的
3、控制數據的共享,在不建立直接關聯的條件下,讓多個不相關的進程或線程之間實現通信
Singleton通過將構造方法限定為private避免了類在外部被實例化,在同一個虛擬機範圍內,Singleton的唯一實例只能通過getInstance()方法訪問。但其實通過Java反射機制是能夠實例化構造方法為private的類的,那基本上會使所有的Java單例實現失效。
雖然也是只有一個線程能夠執行,假如線程B先執行,線程B獲得鎖,線程B執行完之後,線程 A獲得鎖,但是此時沒有檢查singleton是否為空就直接執行了,所以還會出現兩個singleton實例的情況。
既然懶漢式是非線程安全的,那就要改進它。最直接的想法是,給getInstance方法加鎖不就好了,但是我們不需要給方法全部加鎖啊,只需要給方法的一部分加鎖就好了。基於這個考慮,引入了雙檢鎖(Double Check Lock,簡稱DCL)的寫法:
使用volatile 的原因:
對於JVM而言,它執行的是一個個Java指令。在Java指令中創建對象和賦值操作是分開進行的,也就是說instance = new Singleton();語句是分兩步執行的。但是JVM並不保證這兩個操作的先後順序,也就是說有可能JVM會為新的Singleton實例分配空間, 然後直接賦值給instance成員,然後再去初始化這個Singleton實例。這樣就使出錯成為了可能,我們仍然以A、B兩個線程為例:
加載一個類時,其內部類不會同時被加載。一個類被加載,當且僅當其某個靜態成員(靜態域、構造器、靜態方法等)被調用時發生。
枚舉類實現單例模式是 effective java 作者極力推薦的單例實現模式,因為枚舉類型是線程安全的,並且只會裝載一次,設計者充分的利用了枚舉的這個特性來實現單例模式,枚舉的寫法非常簡單,而且枚舉類型是所用單例實現中唯一一種不會被破壞的單例實現模式。因為枚舉類沒有構造方法,可以防止反序列化操作。
1、除枚舉方式外, 其他方法都會通過反射的方式破壞單例,反射是通過調用構造方法生成新的對象,所以如果我們想要阻止單例破壞,可以在構造方法中進行判斷,若已有實例, 則阻止生成新的實例,解決辦法如下:
2、如果單例類實現了序列化接口Serializable, 就可以通過反序列化破壞單例,所以我們可以不實現序列化接口,如果非得實現序列化接口,可以重寫反序列化方法readResolve(), 反序列化時直接返回相關單例對象。
Runtime是一個典型的例子,看下JDK API對於這個類的解釋”每個Java應用程序都有一個Runtime類實例,使應用程序能夠與其運行的環境相連接,可以通過getRuntime方法獲取當前運行時。應用程序不能創建自己的Runtime類實例。”,這段話,有兩點很重要:
1、每個應用程序都有一個Runtime類實例
2、應用程序不能創建自己的Runtime類實例
只有一個、不能自己創建,是不是典型的單例模式?看一下,Runtime類的寫法:
為了節約系統資源,有時需要確保系統中某個類只有唯一一個實例,當這個唯一實例創建成功之後,我們無法再創建一個同類型的其他對象,所有的操作都只能基於這個唯一實例。為了確保對象的唯一性,我們可以通過單例模式來實現。
單例模式應用的場景一般發現在以下條件下:
(1)資源共享的情況下,避免由於資源操作時導致的性能或損耗等。如上述中的日誌文件,應用配置。
(2)控制資源的情況下,方便資源之間的互相通信。如線程池等。
關於單例模式的漫畫分析:
單例模式的優缺點、注意事項、使用場景
Java單例模式是什麼意思?
Java單例模式是確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例,在計算機系統中,線程池、緩存、日誌對象、對話框、打印機、顯卡的驅動程序對象常被設計成單例的模式;
Java單例模式分三種:懶漢式單例、餓漢式單例、登記式單例。
(1)Java單例模式有以下特點:單例類只能有一個實例;單例類必須自己創建自己的唯一實例;單例類必須給所有其他對象提供這一實例。
(2)Java單例模式的應用範圍:每台計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中,每台計算機可以有若干通信端口,系統應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用。
原創文章,作者:QEYTO,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/313468.html