前言
當我們使用單例模式的時候,在實際需求場景中。單例模式可以給我們帶來更好的資源優化。但是同時,他也帶來了線程安全問題,下面使用了7中方式的單例模式,在實際場景中,我們往往不會簡簡單單的使用餓漢模式或者懶漢模式。
代碼
public class Test {
/*
單例模式,懶漢式,線程安全
*/
public static class Singleton {
private final static Singleton INSTANCE =new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
return INSTANCE;
}
}
/*
單例模式,餓漢式,線程下不安全
*/
public static class Singleton2 {
private static Singleton2 INSTANCE = null;
private Singleton2() {
}
public static Singleton2 getINSTANCE(){
if (INSTANCE == null)
INSTANCE = new Singleton2();
return INSTANCE;
}
}
/*
單例模式,餓漢式,線程安全,多線程環境下效率不高
*/
public static class Singleton3 {
private static Singleton3 INSTANCE = null;
private Singleton3() {
}
private static synchronized Singleton3 getINSTANCE(){
if (INSTANCE == null)
INSTANCE = new Singleton3();
return INSTANCE;
}
}
/*
單例模式,懶漢式,變種,線程安全
*/
public static class Singleton4 {
private static Singleton4 INSTANCE = null;
static {
INSTANCE = new Singleton4();
}
private Singleton4(){
}
public static Singleton4 getINSTANCE() {
return INSTANCE;
}
}
/*
單例模式,使用靜態內部類,線程安全【推薦】
*/
public static class Singleton5 {
private final static class SingletonHolder {
private static final Singleton5 INSTANCE = new Singleton5();
}
private Singleton5(){
}
public static Singleton5 getINSTANCE() {
return SingletonHolder.INSTANCE;
}
}
/*
靜態內部類,使用枚舉方式,線程安全【推薦】
*/
public enum Singleton6 {
INSTANCE;
public void whateverMethod() {
}
}
/*
靜態內部類,使用雙重校驗鎖,線程安全【推薦】
*/
public static class Singleton7 {
private volatile static Singleton7 INSTANCE = null;
private Singleton7() {
}
public static Singleton7 getINSTANCE() {
if (INSTANCE == null) {
synchronized (Singleton7.class) {
if (INSTANCE == null)
INSTANCE = new Singleton7();
}
}
return INSTANCE;
}
}
/*
測試
*/
public static void main(String[] args) {
System.out.println(Singleton.getInstance() == Singleton.getInstance());
System.out.println(Singleton2.getINSTANCE() == Singleton2.getINSTANCE());
System.out.println(Singleton3.getINSTANCE() == Singleton3.getINSTANCE());
System.out.println(Singleton4.getINSTANCE() == Singleton4.getINSTANCE());
System.out.println(Singleton5.getINSTANCE() == Singleton5.getINSTANCE());
System.out.println(Singleton6.INSTANCE == Singleton6.INSTANCE);
System.out.println(Singleton7.getINSTANCE() == Singleton7.getINSTANCE());
}
}