所謂單利模式,即只能開啟一個線程,只有一個實例,并且能夠實現自我實例化,主要分為懶漢式和餓漢式。
(1)餓漢式
所謂餓漢式,就好比一個餓漢餓了好久,然后某一天到了餐廳,由于餓了很久,所以進入餐廳就希望所有的食物都已經準備好然后直接吃就可以。在程序中就相當于我們提前創建好了一個對象,類加載的時候就實例化并且創建對象,后續就可以直接拿來用,但是這也有個缺點,就是不管需不需要,他都會自動實例化創建對象,在一些情況下會造成資源的浪費。在線程安全方面,由于餓漢式在線程還沒出現之前就已經實例化了,因此餓漢式線程一定是安全的。
package com.example.mzz.singleInstance;/*** 餓漢式*/
public class SingleInstanceDemo01 {public static void main(String[] args) {//因為是單例模式,只有一個實例,不妨創建兩個實例來看一下這兩個實例指向是否一樣,// 如果一樣則說明只創建了一個實例,是單例模式SingleInstance instance1 = SingleInstance.getInstance(); //靜態成員變量可以直接類.方法來調用SingleInstance instance2 = SingleInstance.getInstance();System.out.println(instance1 == instance2);}
}class SingleInstance{//創建一個靜態成員變量用來存儲對象public static final SingleInstance ins = new SingleInstance();//因為是單例模式,只能有一個對象,所以我們需要將構造器私有化private SingleInstance(){}//寫一個方法,返回該對象public static SingleInstance getInstance(){return ins;}}
運行結果:
單例模式線程安全。可以看到,結果為true,說明確實只創建了一個實例,是單例模式。
(2)懶漢式
懶漢式與餓漢式相反,在類加載的時候,不會實例化對象,而是在外部什么時候調用什么時候new對象。由于懶漢式加載是在使用時才會去new 實例的,new的時候是一個動態的過程,是放到方法中實現的,如果有多個線程去訪問這個實例,但是這個實例還在new,這時候有多少線程就會new出多少個實例,一個方法return一個實例,最終會返回哪個實例不確定,這就使得線程不安全,所以可以通過加一個同步鎖synchronized關鍵字來實現。
package com.example.mzz.singleInstance;public class SingleInstanceDemo02 {public static void main(String[] args) {SingleInstance02 instance1 = SingleInstance02.getIns(); //靜態成員變量可以直接類.方法來調用SingleInstance02 instance2 = SingleInstance02.getIns();System.out.println(instance1 == instance2);}
}class SingleInstance02{public static SingleInstance02 ins; //類加載的時候不會實例化創建對象//構造器私有化private SingleInstance02() {}public static synchronized SingleInstance02 getIns(){//先判斷ins是否為null,如果沒有,則new一個對象if(ins == null){ins = new SingleInstance02();}return ins;}}
?運行結果:
?可以看到,結果為true,說明確實只創建了一個實例,是單例模式。
單例模式應用場景?比較:
1.懶漢式相比較餓漢式而言需要加鎖,效率低
2.餓漢式不管是否需要創建對象,在類加載的時候都會實例化創建對象,比懶漢式浪費空間
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态