單例模式:建立全局的惟一一個實例!安全
一、普通單例多線程
public class Singleton{性能
private Singleton single = null;優化
private Singleton(){this
}線程
public Singleton getSingleton(){對象
if(null ==single ){排序
single = new Singleton(); get
}同步
return single;
}
} 此方法,及其不安全
二、餓漢式
public class Singleton{
private static Singleton single = new Singleton();
private Singleton(){
}
public Singleton getSingleton(){
return single;
}
} 此方式在類加載的時候就建立了單例對象,因爲類在加載的時候對其方法是沒有什麼影響和調用的,因此,設置一個公共方法直接返回實例!此方法是線程安全的,由於此類加載以後實例對象只初始化一次,而且有static修飾,也不會被GC回收,無論多少個線程調用,都只是一個實例!
三、懶漢式
public class Singleton{
private static Singleton single = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(null ==single ){
single = new Singleton();
}
return single;
}
}懶漢式只是在類加載的時候建立了一個引用,可是並無建立對象,只有在用到getSingleton方法的時候纔會去判斷爲null的時候去建立對象,在多線程狀況下此方法也是不安全的,有可能會建立多個對象的狀況!因此咱們對懶漢式進行改進 同步鎖的懶漢式
public class Singleton{
private static Singleton single = null;
private Singleton(){
}
public static synchornized Singleton getSingleton(){
if(null ==single ){
single = new Singleton();
}
return single;
}
}咱們在方法上加上了同步鎖,此時單例是安全的,可是效率會降低,當一個線程進來的時候其餘的線程就只能在外面等待,並不能作其餘的事情,這就是阻塞是工做方式,因而咱們就又對其進行改進,讓他們先判斷再進來
public class Singleton{
private static Singleton single = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(null ==single ){
synchornized (this){
single = new Singleton();
}
}
return single;
}
}這個方法咱們優化了那些不是null的對象判斷,不是null的時候直接返回對象,不在浪費時間進同步鎖裏面了!可是這就會又出現問題,咱們的同步塊兒裏面的就又會出現問題,當兩個線程同時判斷是null的時候,這時候就可能建立兩個對象了!因此咱們就又對其改進,在同步塊兒裏面再進行一次判斷
public class Singleton{
private static Singleton single = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(null ==single ){
synchornized (this){
if(null ==single ){
single = new Singleton();
}
}
}
return single;
}
}咱們對這個單例進行double check,雙檢查,這樣就會保證總會一個線程初始化了就不會在初始化對象了!可是這是對的嗎?不對的,虛擬機在建立對象的時候會進行重排序,進而是性能更加優異!因此 single = new Singleton();這個句子會發生重排序,咱們要用violate去修飾Singleton,具體的violate能夠去看看個人violate關鍵字的意思!因此就變成了這樣
public class Singleton{
private violate static Singleton single = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(null ==single ){
synchornized (this){
if(null ==single ){
single = new Singleton();
}
}
}
return single;
}
}
(待續)