單例模式
解決的問題:保證一個類在記憶體中的對象唯一性.
比如:多程式讀取一個配置檔案時,建議配置檔案封裝成對象。會友善操作其中資料,又要保證多個程式讀到的是同一個配置檔案對象,
就需要該配置檔案對象在記憶體中是唯一的。
如何保證對象唯一性呢?
思想:
1,不讓其他程式建立該類對象。
2,在本類中建立一個本類對象。
3,對外提供方法,讓其他程式擷取這個對象。
步驟:
1,因為建立對象都需要構造函數初始化,隻要将本類中的構造函數私有化,其他程式就無法再建立該類對象;
2,就在類中建立一個私有并靜态的本類的對象;
3,定義一個方法,傳回該對象,讓其他程式可以通過方法就得到本類對象。(作用:可控)
代碼展現:
1,私有化構造函數;
2,建立私有并靜态的本類對象;
3,定義公有并靜态的方法,傳回該對象。
餓漢模式:
class Single{
private Single(){} //私有化構造函數。
private static Single s = new Single(); //建立私有并靜态的本類對象。
public static Single getInstance(){ //定義公有并靜态的方法,傳回該對象。
return s;
}
}
//懶漢式:延遲加載方式。使用到的時候才回去初始化該對象
class Single2{
private Single2(){}
private static Single2 s = null;
public static Single2 getInstance(){
if(s==null)
s = new Single2();
return s;
}
}
在多線程模式中,考慮到性能和線程安全問題,我們一般會選擇下面兩種比較經典的單例模式,在性能提高的同時,又保證了線程的安全.
1.static inner Class
2.dubble check instance
(餓漢模式)static inner Class-内部靜态類的形式
public class Singletion {
private static class InnerSingletion {
private static Singletion single = new Singletion();
}
public static Singletion getInstance(){
return InnerSingletion.single;
}
}
(懶漢模式) dubble check instance-為確定線程安全,需要兩次check
public class DubbleSingleton {
private static DubbleSingleton ds;
public static DubbleSingleton getDs(){
if(ds == null){
try {
//模拟初始化對象的準備時間...
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (DubbleSingleton.class) {
if(ds == null){
ds = new DubbleSingleton();
}
}
}
return ds;
}
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(DubbleSingleton.getDs().hashCode());
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(DubbleSingleton.getDs().hashCode());
}
},"t2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(DubbleSingleton.getDs().hashCode());
}
},"t3");
t1.start();
t2.start();
t3.start();
}
}
輸出結果:
792363696
792363696
792363696