使用靜態(tài)內(nèi)部類(lèi)實(shí)現(xiàn)單例
package com.wkcto.sigleton.p3;
import java.util.Random;
/**
* 使用靜態(tài)內(nèi)部類(lèi)實(shí)現(xiàn)單例
* 在類(lèi)加載內(nèi)存時(shí),就給靜態(tài)內(nèi)部類(lèi)的中的靜態(tài)變量進(jìn)行了初始化,具有固有的線程安全性
*/
public class Singleton {
private Singleton(){}
//定義靜態(tài)內(nèi)部類(lèi),在靜態(tài)內(nèi)部類(lèi)中持有Singleton類(lèi)實(shí)例,并直接初始化
private static class SingletonHandler{
private static Singleton obj = new Singleton();
}
//
public static Singleton getInstance(){
try {
Thread.sleep(new Random().nextInt(50));
} catch (InterruptedException e) {
e.printStackTrace();
}
return SingletonHandler.obj;
}
}
使用靜態(tài)代碼塊實(shí)現(xiàn)單例
package com.wkcto.sigleton.p5;
/**
* 使用靜態(tài)代碼塊實(shí)現(xiàn)單例.
* 與餓漢單例沒(méi)有本質(zhì)區(qū)別,在餓漢單例中會(huì)給靜態(tài)變量顯示初始化, 靜態(tài)變量的顯示初始化經(jīng)過(guò)javac編譯后會(huì)編譯到靜態(tài)代碼塊中.也是在執(zhí)行靜態(tài)代碼塊時(shí),給餓漢單例的靜態(tài)實(shí)例進(jìn)行初始化
*/
public class Singleton {
private Singleton(){}
private static Singleton obj;
static {
obj = new Singleton();
}
public static Singleton getInstance(){
return obj;
}
}
使用枚舉類(lèi)型實(shí)現(xiàn)的單例
枚舉enum和靜態(tài)代碼塊的特性相似,在使用枚舉時(shí),構(gòu)造方法會(huì)自動(dòng)調(diào)用.單例的枚舉實(shí)現(xiàn)在書(shū)中被作者所推崇,因?yàn)楣δ芡晟?使用簡(jiǎn)潔,在面對(duì)復(fù)雜的序列化或者反射攻擊時(shí)依然可以防止多次實(shí)例化。
package com.wkcto.sigleton.p6;
/**
* 使用枚舉類(lèi)型實(shí)現(xiàn)的單例
*/
public class Singleton {
private Singleton(){}
//定義內(nèi)部枚舉類(lèi)型
private enum SingletonEnum{
//枚舉對(duì)象天生就是單例
INSTANCE;
private Singleton obj; //定義單例的引用
//在枚舉的構(gòu)造方法中對(duì)單例 的引用賦值
SingletonEnum(){
System.out.println("JVM保證枚舉類(lèi)型的構(gòu)造方法只能調(diào)用一次,這是枚舉類(lèi)型的特點(diǎn)");
obj = new Singleton();
}
private Singleton getInstance(){
return obj;
}
}
//提供一個(gè)公共的對(duì)外接口
public static Singleton getInstance(){
return SingletonEnum.INSTANCE.getInstance();
}
}