單例模式寫法千千萬 總共分為四大類:
懶漢式餓漢式
註冊式threadlocal
public
class
hungrysingleton
public
static hungrysingleton getinstance()
}
特點:
·執行緒安全,但容易造成資源浪費,如果不instance不被使用,這個物件就占用無意義的記憶體
public
class
lazysingleton
public
static lazysingleton getinstance()
return instance;
}}
特點
·不浪費記憶體 但是執行緒不安全 舉例說明 如果t1 執行緒判斷例項為空 開始建立物件並賦值
在建立物件過程中 t2進入 也發現例項為空 所以又會建立物件 這樣打破了單例規則
public
class
lazysingleton
public
synchronized
static lazysingleton getinstance()
return instance;
}}
特點
·不浪費記憶體 執行緒安全 但當例項已經建立完成的時候依然會上鎖 非常影響效能
public
class
doublecheck
public
static doublecheck getinstance()
}}return instance;
}}
特點
懶漢式上鎖的變種
·絕大部分解決了效率問題 可惜也有執行緒安全性問題
下面詳解
在《併發程式設計的藝術》一書中提到過 在**標記處 可能出現記憶體指令重排
標記處一共經歷了三件事
分配記憶體位址 memory
建立物件 初始化物件
賦值 memory = 物件
這個過程是完全符合指令重排的要求的 如果發生了指令重排 會變成
}}
增加volatile關鍵字禁止指令重排
public
class
staticinner
public
static staticinner getinstance()
private
static
class
a}
看似像餓漢 其實是懶漢
利用的是jvm機制 jvm對於內部類是延遲載入的 當內部類被使用到的時候才會載入
自動幫我們做了懶漢式的處理
但是能被反射破壞
我們可以通過反射獲取私有的構造方法 手動呼叫
我們可以在構造方法中丟擲異常
private
aaa(
)}
public
enum enumsingleton
public object getobject()
public enumsingleton setobject
(object object)
}
直接呼叫getinstance方法 得到的例項一定是單例的 然後通過setobject 進行屬性賦值
列舉在jdk層面就已經定義了不能使用構造方法建立
設計模式 單例模式 全
就是採取一定的方法保證在整個的軟體系統中,對某個類只能存在乙個物件例項,並且該類只提供乙個取得其物件例項的方法.1.餓漢式 靜態常量 餓漢式 靜態常量 public class singletontest1 class singleton 構造器私有化 3.對外提供乙個公有的靜態方法,返回例項物件 ...
單例模式 單例模式
餓漢式 急切例項化 public class eagersingleton 2.宣告靜態成員變數並賦初始值 類初始化的時候靜態變數就被載入,因此叫做餓漢式 public static eagersingleton eagersingleton new eagersingleton 3.對外暴露公共的...
單例 單例模式
簡單的實現乙個單例 instancetype sharedinstance return instance 真正的單例模式 myclass sharedinstance return instance id allocwithzone nszone zone return nil id copywi...