單例設計模式我這裏就只寫五種方式進行實現
1、餓漢模式
餓漢模式天生線程安全。因爲一開始就創建了對象
步驟:
1、一開始就使用static 方法創建自己
2、將構造函數私有
3、對外提供一個方法獲取到自己
/**
* 單例模式創建方式一: 餓漢模式創建
*
* @author liyue
* @date 2020/2/12 15:44
*/
public class User {
//1.一開始就創建對象
public static User user = new User();
//2.私有化構造方法
private User() {
}
//3.提供一個對外的可以獲取當前對象的方法
public static User getUser() {
return user;
}
}
2、懶漢模式
創建步驟:
-
一開始只使用static 定義自己
-
構造方法私有
-
對外提供一個可以獲取到對象的接口,如果該對象爲null就重新new一個對象返回。如果對象不爲
null就放當前對象。
/**
* 單例模式創建方式二: 懶漢模式
*
* @author liyue
* @date 2020/2/12 15:50
*/
public class User {
//1.開始只定義自己
private static User user;
//2.構造方法私有化
private User() {
}
//3.對外提供一個可以獲取到對象的方法
public static User getUser() {
//多線程訪問的時候會線程不安全
if (user == null) {
user = new User();
return user;
}
return user;
}
}
3、加鎖的懶漢模式
package com.leeue.sigle;
/**
* 單例模式創建方式三: 線程安全加鎖的 懶漢模式
*
* @author liyue
* @date 2020/2/12 17:14
*/
public class User {
private static User user;
private User() {
}
// 加了 synchronized 鎖 就可以保證只有一個線程進行訪問。
public static synchronized User getUser() {
if (user == null) {
user = new User();
return user;
}
return user;
}
}
4、懶漢模式雙重校驗鎖方式實現
/**
* 單例模式創建方式四: 雙重校驗鎖餓漢模式
*
* @author liyue
* @date 2020/2/12 17:17
*/
public class User {
//加上volatile 關鍵字,user就對線程有了可見性
private static volatile User user;
private User() {
}
public static User getUser() {
if (user == null) {
//使用 synchronized 包裹代碼塊。雙重判斷。static 修飾的鎖是字節碼文件
synchronized (User.class) {
if (user == null) {
user = new User();
return user;
}
}
}
return user;
}
}
5、使用枚舉方式實現單例
在java中枚舉是天生安全的
/**
* 單例模式創建方式五: 使用枚舉方式創建實現單例模式
*
* @author liyue
* @date 2020/2/12 17:27
*/
public class User {
//1.定義枚舉裏面複製創建對象
private static enum UserEnum {
GET_USER;
private User user;
private UserEnum() {
user = new User();
}
public User getUser() {
return user;
}
}
//2.私有構造方法
private User() {
}
//3.提供一個對外獲取對象的方法
private static User getUser() {
return UserEnum.GET_USER.getUser();
}
}