單例模式大概是最直觀的一種設計模式了,儘管直觀卻不簡單。
數學與邏輯學中,singleton定義為「有且僅有乙個元素的集合」,
單例模式可以如下定義:「乙個類有且僅有乙個例項,並且自行例項化向整個系統提供」。
我比較喜歡design patterns一書中的描述"保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點"。
1.單例類只能有乙個例項
2.單例類必須自己自己建立自己的唯一例項
3.例類必須給所有其他物件提供這一例項
實現單例,可以將類的構造方法限定為private,避免在外部例項化,然後在類中提供乙個靜態的例項並能夠返回給使用者,
在同乙個虛擬機器範圍內,singleton的唯一例項只能通過getinstance方法訪問。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public
class
singleton
public
static
singleton getinstance()
return
uniqueinstance;
}
}
經典的實現方法並沒有考慮多執行緒的環境,試想存在兩個執行緒a和b,
同時呼叫getinstance方法,執行緒a檢查uniqueinstance是null,開始建立例項;
同時執行緒b檢測到uniqueinstance是null,於是執行緒a/b各自建立了物件。
解決這個問題最簡單的方法是加鎖,為getinstance的靜態方法新增synchronized關鍵字,
但是考慮到synchronized同步鎖的效能較低,可以調整synchronized新增(加鎖)的位置。 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public
class
singletonsafed
//注意設定為靜態方法
public
static
singletonsafed getinstance()
}
}
return
uniqueinstance;
}
}
另外,一些文件會提到單例模式的三種形式(懶漢式,餓漢式,登記式),
其實餓漢式和懶漢式主要是執行緒安全的區別,同時懶漢式是延遲載入,
在需要的時候才建立物件,而餓漢式在虛擬機器啟動的時候就會建立,例如下面**: 1
2
3
4
5
6
7
8
9
10
11
//餓漢式單例類.在類初始化時,已經自行例項化
public
class
singleton1
//已經自行例項化
private
static
final
singleton1 single =
new
singleton1();
//靜態工廠方法
public
static
singleton1 getinstance()
}
懶漢式單例: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
//懶漢式單例類.在第一次呼叫的時候例項化
public
class
singleton2
//注意,這裡沒有final
private
static
singleton2 single=
null
;
//靜態工廠方法
public
synchronized
static
singleton2 getinstance()
return
single;
}
}
設計模式筆記 Singleton
單例模式singleton 建構函式定義為private的作用是阻止類在外部被例項化。定義顯式建構函式則預設的建構函式會失效。保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。定義乙個靜態方法 package singleton.pattern public class singleton 單...
設計模式學習筆記 九 Singleton模式
設計模式 一書對singleton模式是這樣描述的 保證乙個類只有乙個例項,並提供乙個訪問它的全域性訪問點。這個模式比較簡單,下面給出乙個例子 public class singleton public static singleton getinstance 這個程式在單執行緒下執行不會有問題,但...
設計模式學習筆記 九 Singleton模式
設計模式 一書對singleton模式是這樣描述的 保證乙個類只有乙個例項,並提供乙個訪問它的全域性訪問點。這個模式比較簡單,下面給出乙個例子 public class singleton public static singleton getinstance 這個程式在單執行緒下執行不會有問題,但...