單例(singleton):只允許創(chuàng)建一個該類的對象址愿。
① 單例模式:餓漢式(線程安全、占資源)
- 天生線程安全(無鎖)兴喂、類加載時創(chuàng)建(不用也會被創(chuàng)建肛走,占用資源)
public class TestSingleton {
public static void main(String[] args) {
Singleton1 s1 = Singleton1.getInstance();
Singleton1 s11 = Singleton1.getInstance();
System.out.println(s1); // Singleton1@7852e922
System.out.println(s11); // Singleton1@7852e922
}
}
class Singleton1 {
// 私有靜態(tài)常量引用,類加載執(zhí)行就1份嘱腥、不可調用耕渴、不可修改(始終單例)
private static final Singleton1 instance = new Singleton1();
// 私有構造,不可直接new對象
private Singleton1() {}
// 靜態(tài)方法齿兔,類名直接調用橱脸,返回私有靜態(tài)常量引用
public static Singleton1 getInstance() {
return instance;
}
}
② 單例模式:懶漢式(不安全、需要同步)
- 天生線程不安全(需同步鎖分苇、效率低)添诉、使用時才創(chuàng)建
public class TestSingleton {
public static void main(String[] args) {
Singleton2 s2 = Singleton2.getInstance();
Singleton2 s22 = Singleton2.getInstance();
System.out.println(s2); // Singleton2@4e25154f
System.out.println(s22); // Singleton2@4e25154f
}
}
class Singleton2 {
// 私有靜態(tài)引用,類加載執(zhí)行就1份医寿、不可調用
private static Singleton2 instance = null;
// 私有構造栏赴,不可直接new對象
private Singleton2() {}
// 同步鎖、靜態(tài)方法獲取類的對象(引用為空則new靖秩,不為空則返回自身须眷,始終單例)
public synchronized static Singleton2 getInstance() {
return instance == null ? instance = new Singleton2() : instance;
}
}
③ 單例模式:懶漢式(線程安全竖瘾,靜態(tài)內部類)
- 天生線程安全(無鎖),使用時才創(chuàng)建(靜態(tài)內部類)
public class TestSingleton {
public static void main(String[] args) {
Singleton3 s3 = Singleton3.getInstance();
Singleton3 s33 = Singleton3.getInstance();
System.out.println(s3); // Singleton3@70dea4e
System.out.println(s33); // Singleton3@70dea4e
}
}
class Singleton3 {
// 私有構造花颗,不可直接new對象
private Singleton3() {}
// 靜態(tài)內部類捕传,不依賴外部類,使用時才需要創(chuàng)建捎稚,可獨立創(chuàng)建
// 內部類中靜態(tài)常量引用乐横,一旦創(chuàng)建內部類,屬性則不可修改(始終單例)
private static class Holder {
static final Singleton3 instancce = new Singleton3();
}
// 靜態(tài)方法今野,獲取內部類中創(chuàng)建的外部類對象的常量引用
public static Singleton3 getInstance() {
return Holder.instancce;
}
}