java單例模式的四種實作方式
餓漢式、懶漢式、雙重驗證鎖機制、靜态内部類
餓漢式
餓漢式就是不管怎麼樣都會直接建立一個對象給你
public class SingletonErhan {
/**
* 單例模式之餓漢式
*/
private static SingletonErhan singletonErhan = new SingletonErhan();
private SingletonErhan(){
}
public static SingletonErhan getSingletonErhan(){
return singletonErhan;
}
}
測試類
public class TestDemo {
//測試餓漢式
@Test
public void testSingletonErhan(){
SingletonErhan singletonErhan = SingletonErhan.getSingletonErhan();
SingletonErhan singletonErhan1 = SingletonErhan.getSingletonErhan();
System.out.println(singletonErhan);
System.out.println(singletonErhan1);
}
}
列印資訊

懶漢式
建立一個類
public class SingletonLahan {
/**
* 單例模式懶漢式
*/
private static SingletonLahan singletonLahan;
private SingletonLahan(){
}
public static SingletonLahan getSingletonLahan(){
if (singletonLahan == null){
singletonLahan = new SingletonLahan();
}
return singletonLahan;
}
}
先私有化一個靜态對象,不設定任何值然後建立一個擷取對象的共有靜态方法當我們需要的時候就去直接調用這個共有靜态方法先要判斷對象是否為空,為空的話直接new一個對象指派給室私有靜态成員變量(相當于給對象初始化),因為是靜态的隻初始化一次,存放在棧中;
測試:
//測試懶漢模式
@Test
public void testSingletonLanHan(){
SingletonLahan singletonLahan = SingletonLahan.getSingletonLahan();
SingletonLahan singletonLahan1 = SingletonLahan.getSingletonLahan();
System.out.println(singletonLahan);
System.out.println(singletonLahan1);
}
雙重驗證
建立一個類
public class SingletonSycn {
/**
* 雙重驗證鎖機制
*/
private static SingletonSycn singleton;
private SingletonSycn() {
}
public static SingletonSycn getSingleton() {
if (singleton == null) {
synchronized (SingletonSycn.class) {
if (singleton == null) {
singleton = new SingletonSycn();
}
}
}
return singleton;
}
}
我們需要使用到synchronized同步鎖來阻止多線程的情況下産生的安全問題
第一個if是判斷該對象是否為空,當一個線程進入到synchronized同步代碼塊中其他線程就隻能在外面等待,此時再次進行判斷對象是否為空是驗證該對象是否被其它線程搶先進入并且初始化對象,如果有直接傳回,如果沒有進行初始化對象
測試:
//測試雙重驗證鎖機制
@Test
public void testSingletonSycn(){
SingletonSycn singleton = SingletonSycn.getSingleton();
SingletonSycn singleton1 = SingletonSycn.getSingleton();
System.out.println(singleton);
System.out.println(singleton1);
}
靜态内部類
public class SingletonClass {
/**
* 單例模式之匿名内部類
*/
private SingletonClass(){
}
private static class InnerClass{
private static SingletonClass singletonClass = new SingletonClass();
}
public static SingletonClass getSinletonClass(){
return InnerClass.singletonClass;
}
}
直接在内部類内部就把對象進行初始化,這樣很安全。可以讓建立次對象時無法直接去通路我們的私有内部類
測試
//測試私有匿名内部類
@Test
public void testSingletonClass(){
SingletonSycn singleton = SingletonSycn.getSingleton();
SingletonSycn singleton1 = SingletonSycn.getSingleton();
System.out.println(singleton);
System.out.println(singleton1);
}