單例模式
-
單例模式(餓漢式)
public class Demo { public static void main(String[] args) throws IOException { // 獲取Singleton對象 Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); } } class Singleton { private static Singleton _instance = new Singleton(); // 私有構造方法 private Singleton() { } /** * 獲取本類對象(餓漢式) * * @return Singleton */ public static Singleton getInstance() { return Singleton._instance; } }
-
單例模式(懶漢式)
public class Demo { public static void main(String[] args) throws IOException { // 獲取Singleton對象 Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); } } class Singleton { private static Singleton _instance = null; // 私有構造方法 private Singleton() { } /** * 獲取本類對象(懶漢式) * * @return Singleton */ public static Singleton getInstance() { if (Singleton._instance == null) { Singleton._instance = new Singleton(); } return Singleton._instance; } }
推薦餓漢式
==在懶漢式下,多線程會創建多個對象。排除多線程后,可以使用懶漢式。==
- 解決單例模式線程安全
// 解決方案1
public class Demo {
public static void main(String[] args) throws IOException {
// 獲取Singleton對象
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
}
class Singleton {
private static Singleton _instance = null;
// 私有構造方法
private Singleton() {
}
/**
* 獲取本類對象(懶漢式)
*
* @return Singleton
*/
public static Singleton getInstance() {
if (Singleton._instance == null) {
synchronized (Singleton.class){
if(Singleton._instance == null){
Singleton._instance = new Singleton();
}
}
}
return Singleton._instance;
}
}
// 解決方案2
public class Demo {
public static void main(String[] args) throws IOException {
// 獲取Singleton對象
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
}
class Singleton {
// 私有構造方法
private Singleton() {
}
/**
* 獲取本類對象(懶漢式)
*
* @return Singleton
*/
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
/**
* 單例模式類鎖
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
}
以上兩種現成安全方案可以解決單例模式的線程安全問題
==說明:第二種方式在線程1進入方法后暫停,線程2進入方法后率先完成實例化,線程1再次實例化的時候由于INSTANCE是you由final修飾,所以不會創建多個對象!!!==