使用靜態內部類實現單例
package com.wkcto.sigleton.p3;
import java.util.Random;
/**
* 使用靜態內部類實現單例
* 在類加載內存時,就給靜態內部類的中的靜態變量進行了初始化,具有固有的線程安全性
*/
public class Singleton {
private Singleton(){}
//定義靜態內部類,在靜態內部類中持有Singleton類實例,并直接初始化
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;
}
}
使用靜態代碼塊實現單例
package com.wkcto.sigleton.p5;
/**
* 使用靜態代碼塊實現單例.
* 與餓漢單例沒有本質區別,在餓漢單例中會給靜態變量顯示初始化, 靜態變量的顯示初始化經過javac編譯后會編譯到靜態代碼塊中.也是在執行靜態代碼塊時,給餓漢單例的靜態實例進行初始化
*/
public class Singleton {
private Singleton(){}
private static Singleton obj;
static {
obj = new Singleton();
}
public static Singleton getInstance(){
return obj;
}
}
使用枚舉類型實現的單例
枚舉enum和靜態代碼塊的特性相似,在使用枚舉時,構造方法會自動調用.單例的枚舉實現在書中被作者所推崇,因為功能完善,使用簡潔,在面對復雜的序列化或者反射攻擊時依然可以防止多次實例化。
package com.wkcto.sigleton.p6;
/**
* 使用枚舉類型實現的單例
*/
public class Singleton {
private Singleton(){}
//定義內部枚舉類型
private enum SingletonEnum{
//枚舉對象天生就是單例
INSTANCE;
private Singleton obj; //定義單例的引用
//在枚舉的構造方法中對單例 的引用賦值
SingletonEnum(){
System.out.println("JVM保證枚舉類型的構造方法只能調用一次,這是枚舉類型的特點");
obj = new Singleton();
}
private Singleton getInstance(){
return obj;
}
}
//提供一個公共的對外接口
public static Singleton getInstance(){
return SingletonEnum.INSTANCE.getInstance();
}
}