分享一波:程序員賺外快-必看的巔峰干貨
前言
近期預計1-2周左右會更新設計模式專題文章。
單例設計模式:保證在一個JVM中,只能存在一個實例。
應用場景:Servlet,Spring IOC,線程池,連接池,Spring AOP
單例設計模式的優缺點
好處:節約內存,重復利用,方便管理
缺點:存在線程安全問題
單例設計模式分類
-
餓漢式:類初始化時,會立即加載該對象,線程天生安全,調用效率高。
-
懶漢式: 類初始化時,不會初始化該對象,真正需要使用的時候才會創建該對象,具備懶加載功能。
-
靜態內部方式:結合了懶漢式和餓漢式各自的優點,真正需要對象的時候才會加載,加載類是線程安全的。
-
枚舉單例: 使用枚舉實現單例模式 優點:實現簡單、調用效率高,枚舉本身就是單例,由jvm從根本上提供保障。避免通過反射和反序列化的漏洞, 缺點沒有延遲加載。
5.雙重檢測鎖方式 (因為JVM本質重排序的原因,可能會初始化多次,不推薦使用)
其中 ,餓漢式和懶漢式使用最為普遍
餓漢式創建單例
/**
-
餓漢式
/
public class User01 {
/*- 類初始化時,會立即加載該對象,線程天生安全,調用效率高
*/
private static User01 singletonDemo01 = new User01();
private User01() {
System.out.println(“SingletonDemo01初始化”);
}public static User01 getInstance() {
System.out.println(“getInstance”);
return singletonDemo01;
}public static void main(String[] args) {
User01 s1 = User01.getInstance();
User01 s2 = User01.getInstance();
System.out.println(s1 == s2);
} - 類初始化時,會立即加載該對象,線程天生安全,調用效率高
}
懶漢式創建單例
/**
-
懶漢式
*/
public class User02 {/**
- 類初始化時,不會初始化該對象,真正需要使用的時候才會創建該對象。
*/
private static User02 singletonDemo02;
private User02() {
}
public synchronized static User02 getInstance() {
if (singletonDemo02 == null) {
singletonDemo02 = new User02();
}
return singletonDemo02;
}public static void main(String[] args) {
User02 s1 = User02.getInstance();
User02 s2 = User02.getInstance();
System.out.println(s1 == s2);
} - 類初始化時,不會初始化該對象,真正需要使用的時候才會創建該對象。
}
靜態內部類方式創建單例
/**
-
靜態內部類方式
*/
public class SingletonDemo03 {
private SingletonDemo03() {
System.out.println(“初始化…”);
}public static class SingletonClassInstance {
private static final SingletonDemo03 singletonDemo03 = new SingletonDemo03();
}// 方法沒有同步
public static SingletonDemo03 getInstance() {
System.out.println(“getInstance”);
return SingletonClassInstance.singletonDemo03;
}public static void main(String[] args) {
SingletonDemo03 s1 = SingletonDemo03.getInstance();
SingletonDemo03 s2 = SingletonDemo03.getInstance();
System.out.println(s1 == s2);
}
}
優勢:兼顧了懶漢模式的內存優化(使用時才初始化)以及餓漢模式的安全性(不會被反射入侵)。
劣勢:需要兩個類去做到這一點,雖然不會創建靜態內部類的對象,但是其 Class 對象還是會被創建,而且是屬于永久帶的對象。
枚舉方式創建單例
enum UserEnum {
HTTP_200(200, “請求成功”),HTTP_500(500,“請求失敗”);
private Integer code;
private String name;
UserEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {this.code = code;
}public String getName() {return name;
}public void setName(String name) {this.name = name;
}
}
public class TestEnum {
public static void main(String[] args) {System.out.println(UserEnum.HTTP_500.getCode());
}
}
public class User {
public static User getInstance() {
return SingletonDemo04.INSTANCE.getInstance();
}
private static enum SingletonDemo04 {INSTANCE;// 枚舉元素為單例private User user;private SingletonDemo04() {System.out.println("SingletonDemo04");user = new User();}public User getInstance() {return user;}
}public static void main(String[] args) {
User u1 = User.getInstance();
User u2 = User.getInstance();
System.out.println(u1 == u2);
}
}
分享一波:程序員賺外快-必看的巔峰干貨
如果以上內容對你覺得有用,并想獲取更多的賺錢方式和免費的技術教程
請關注微信公眾號:HB荷包
一個能讓你學習技術和賺錢方法的公眾號,持續更新