一:什麼是單例?
單例保證一個對象在JVM中只能被實例化一次,常見單例模式有:懶漢式、餓漢式。
二:結構圖
三:懶漢式
由於懶漢式是需要的時候纔會去實例化,所有是線程不安全的
package com.zz.designpattern;
/**
* 懶漢式
*
* @Title Singleton01
* @Description
* @author Zheng.Zeng
* @date 2018年7月12日 下午3:20:35
*/
public class Singleton01 {
private static volatile Singleton01 instanse;
// 私有化 防止其他類利用new來創建對象
private Singleton01 () {
}
public static Singleton01 getInstanse () {
if (instanse == null) {
instanse = new Singleton01 ();
}
return instanse;
}
}
四:雙重鎖定
由於懶漢式會出現線程安全問題,所以我們可以通過synchronized鎖或者lock鎖來解決線程按鈕問題,但是問題來了,上鎖之後會影響性能問題怎麼辦呢? 當然我們可以使用雙重鎖定來解決性能問題。爲什麼說雙重鎖定可以解決性能問題呢? 因爲第一個判斷是用來減少進入鎖的線程數,而第二個判斷用來防止多線程重複實例化對象。 這麼一說是不是比直接用鎖的性能要好呢?
package com.zz.designpattern;
/**
* 懶漢式 雙重鎖定
*
* @Title Singleton03
* @Description
* @author Zheng.Zeng
* @date 2018年7月12日 下午3:25:41
*/
public class Singleton03 {
private static volatile Singleton03 instanse;
private Singleton03 () {
};
public static Singleton03 getInstanse () {
if (instanse == null) {
synchronized (Singleton03.class) {
if (instanse == null) {
instanse = new Singleton03 ();
}
}
}
return instanse;
}
}
五:餓漢式
package com.zz.designpattern;
/**
* 餓漢式
*
* @Title Singleton02
* @Description
* @author Zheng.Zeng
* @date 2018年7月12日 下午3:22:41
*/
public class Singleton02 {
private static Singleton02 instanse = new Singleton02 ();
private Singleton02 () {
}
public static Singleton02 getInstanse () {
return instanse;
}
}
六:比較實例類
package com.zz.designpattern;
public class Test {
public static void main (String[] args) {
// Singleton01 s1 = Singleton01.getInstanse ();
// Singleton01 s2 = Singleton01.getInstanse ();
// Singleton02 s1 = Singleton02.getInstanse ();
// Singleton02 s2 = Singleton02.getInstanse ();
Singleton03 s1 = Singleton03.getInstanse ();
Singleton03 s2 = Singleton03.getInstanse ();
if (s1 == s2) {
System.out.println ("相同");
}
}
}