單例模式
通俗的講,有懶漢和餓漢模式崔赌,一般很少用餓漢模式意蛀,因?yàn)榭紤]到對象的資源消耗等,一般只有在需要的時(shí)候才會(huì)初始化實(shí)例對象健芭,由于多線程實(shí)例化县钥,字節(jié)碼重排序,又有了雙重檢查鎖等實(shí)現(xiàn)方式慈迈,但由于性能和代碼量的因素若贮,內(nèi)部類和枚舉實(shí)現(xiàn)是最有效的方式.以下是靜態(tài)內(nèi)部類和枚舉實(shí)現(xiàn)過程.
內(nèi)部類實(shí)現(xiàn)
/**
* 這些情況下就不用自己再來進(jìn)行同步控制了。這些情況包括:
*
* 1.由靜態(tài)初始化器(在靜態(tài)字段上或static{}塊中的初始化器)初始化數(shù)據(jù)時(shí)
*
* 2.訪問final字段時(shí)
*
* 3.在創(chuàng)建線程之前創(chuàng)建對象時(shí)
*
* 4.線程可以看見它將要處理的對象時(shí)
*
* @author earthlyfisher
*
*/
public class SingleInstance {
private SingleInstance() {
super();
}
/**
* 類級(jí)的內(nèi)部類痒留,也就是靜態(tài)的成員式內(nèi)部類谴麦,該內(nèi)部類的實(shí)例與外部類的實(shí)例 沒有綁定關(guān)系,而且只有被調(diào)用到時(shí)才會(huì)裝載伸头,從而實(shí)現(xiàn)了延遲加載匾效。
*/
private static class InstanseHolder {
static{
System.out.println("內(nèi)部類加載");
}
/**
* 靜態(tài)初始化器,由JVM來保證線程安全
*/
public static final SingleInstance instanse = new SingleInstance();
}
public static SingleInstance getInstance() {
/**
* 當(dāng)getInstance方法第一次被調(diào)用的時(shí)候恤磷,它第一次讀取SingletonHolder.instance面哼,
* 導(dǎo)致SingletonHolder類得到初始化;而這個(gè)類在裝載并被初始化的時(shí)候扫步,會(huì)初始化它的靜態(tài)域魔策,從而創(chuàng)建Singleton的實(shí)例,
* 由于是靜態(tài)的域河胎,因此只會(huì)在虛擬機(jī)裝載類的時(shí)候初始化一次闯袒,并由虛擬機(jī)來保證它的線程安全性。
*/
return InstanseHolder.instanse;
}
}
枚舉
/**
* 1.線程安全游岳,通過類加載器保證線程安全搁吓。
* 2.抗序列化問題:枚舉類自己實(shí)現(xiàn)了readResolve()方法,所以抗序列化吭历,這個(gè)方法是當(dāng)前類自己實(shí)現(xiàn)的(解決)
* @author earthlyfisher
*
*/
public enum SingleInstanceByEnum {
instance;
/**
* 單例可以有自己的操作
*/
public void singletonOperation() {
System.out.println("hello world");
}
}