㈠ 在java開發中,為什麼要使用單例模式
java單例模式確保一個類只有一個實例,自行提供這個實例並向整個系統提供這個實例。x0dx0a特點:x0dx0a1,一個類只能有一個實例;x0dx0a2,自己創建這個實例;x0dx0a3,整個系統都要使用這個實例。x0dx0a--------------------------------x0dx0aSingleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。在很多操作中,比如建立目錄 資料庫連接都需要這樣的單線程操作。一些資源管理器常常設計成單例模式。x0dx0a外部租缺資源:譬如每台計算機可以有若干個列印機,但只能有一個Printer Spooler,以避免兩個列印作業同時輸出到列印機中。每台亂型消計算機可以有若干個通信埠,系統應當集中管理這些通信埠,以避免嘩知一個通信埠被兩個請求同時調用。x0dx0a內部資源,譬如,大多數的軟體都有一個(甚至多個)屬性文件存放系統配置。這樣的系統應當由一個對象來管理這些屬性文件。x0dx0a--------------------------------x0dx0a單例模式,能避免實例重復創建;x0dx0a單例模式,應用於避免存在多個實例引起程序邏輯錯誤的場合;x0dx0a單例模式,較節約內存。
㈡ 如何在Java中實現單例模式
單例模式大致有五種寫法,分別為懶漢,惡漢,靜態內部類,枚舉和雙重校驗鎖。
1、懶漢寫法,常用寫法
classLazySingleton{
;
privateLazySingleton(){
}
(){
if(singleton==null){
singleton=newLazySingleton();
}
returnsingleton;
}
}
2、惡漢寫法,缺點是沒有達到lazy loading的效果
classHungrySingleton{
=newHungrySingleton();
privateHungrySingleton(){}
(){
returnsingleton;
}
}
3、靜態內部類,優點:載入時不會初始化靜態變數INSTANCE,因為沒有主動使用,達到Lazy loading
classInternalSingleton{
{
=newInternalSingleton();
}
privateInternalSingleton(){}
(){
returnSingletonHolder.INSTANCE;
}
}
4、枚舉,優點:不僅能避免多線程同步問題,而且還能防止反序列化重新創建新的對象
enumEnumSingleton{
INSTANCE;
publicvoiddoSomeThing(){
}
}
5、雙重校驗鎖,在當前的內存模型中無效
classLockSingleton{
;
privateLockSingleton(){}
//詳見:http://www.ibm.com/developerworks/cn/java/j-dcl.html
(){
if(singleton==null){
synchronized(LockSingleton.class){
if(singleton==null){
singleton=newLockSingleton();
}
}
}
returnsingleton;
}
}
參考自:http://www.oschina.net/code/snippet_107039_6062
㈢ 如何寫一個標準的Java單例模式
java中單例模式是一種常見的設計模式,單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。
單例模式有一下特點:
1、單例類只能有一個實例。
2、單例類必須自己自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
單例模式確保某個類只有一個實例,而且自行實例化並向整個系統提供這個實例。在計算機系統中,線程池、緩存、日誌對象、對話框、列印機、顯卡的驅動程序對象常被設計成單例。這些應用都或多或少具有資源管理器的功能。每台計算機可以有若干個列印機,但只能有一個Printer Spooler,以避免兩個列印作業同時輸出到列印機中。每台計算機可以有若干通信埠,系統應當集中管理這些通信埠,以避免一個通信埠同時被兩個請求同時調用。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。
首先看一個經典的單例實現。
public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Other methods...
}
Singleton通過將構造方法限定為private避免了類在外部被實例化,在同一個虛擬機范圍內,Singleton的唯一實例只能通過getInstance()方法訪問。(事實上,通過Java反射機制是能夠實例化構造方法為private的類的,那基本上會使所有的Java單例實現失效。此問題在此處不做討論,姑且掩耳盜鈴地認為反射機制不存在。)
但是以上實現沒有考慮線程安全問題。所謂線程安全是指:如果你的代碼所在的進程中有多個線程在同時運行,而這些線程可能會同時運行這段代碼。如果每次運行結果和單線程運行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是線程安全的。或者說:一個類或者程序所提供的介面對於線程來說是原子操作或者多個線程之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題。顯然以上實現並不滿足線程安全的要求,在並發環境下很可能出現多個Singleton實例。
//////////////////////////////////////////////////////////////////////
驗證單例模式的示例
//////////////////////////////////////////////////////////////////////
public class TestStream {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 該類只能有一個實例
private TestStream() {
} // 私有無參構造方法
// 該類必須自行創建
// 有2種方式
private static TestStream ts1 = null;
// 這個類必須自動向整個系統提供這個實例對象
public static TestStream getTest() {
if (ts1 == null) {
ts1 = new TestStream();
}
return ts1;
}
public void getInfo() {
System.out.println("output message " + name);
}
public static void main(String[] args) {
TestStream s = TestStream.getTest();
s.setName("張孝祥 1");
System.out.println(s.getName());
TestStream s1 = TestStream.getTest();
s1.setName("張孝祥 2");
System.out.println(s1.getName());
s.getInfo();
s1.getInfo();
if (s == s1) {
System.out.println("創建的是同一個實例");
} else if (s != s1) {
System.out.println("創建的不是同一個實例");
} else {
System.out.println("application error");
}
}
}
////////////////////////////////////////////