Mybatis源碼中設計模式很多,我從裏面撈起來九種,在此分享:
一、單例模式。
單例模式六種常見的寫法。
package designPattern;
/**
* 單例模式:線程安全、反序列化
*/
public class SigleTon {
// 1、餓漢模式
static SigleTon sigleTon = new SigleTon();
private SigleTon getInstance(){
return sigleTon;
}
}
class SigleTon02 {
SigleTon02 sigleTon02;
// 2、餓漢模式 -- 線程不安全
private SigleTon02 getInstance(){
if(sigleTon02==null)
return new SigleTon02();
else
return sigleTon02;
}
}
class SigleTon03 {
// 3、餓漢模式 -- 線程安全 -- 靜態內部類
/**
* 爲什麼線程安全:因爲 SigleTonInstance的sigleTon在類的初始化階段被實例化。
* 而類的初始化階段是線程安全的。
*/
private SigleTon03 getInstance(){
return SigleTonInstance.sigleTon;
}
static class SigleTonInstance{
private static SigleTon03 sigleTon = new SigleTon03();
}
}
class SigleTon04 {
enum SigleTon{
A,B,C,D
}
SigleTon sigleTon;
// 4、餓漢模式 -- 枚舉
private SigleTon getInstance(){
return sigleTon;
}
}
class SigleTon05 {
SigleTon05 sigleTon;
// 5、餓漢模式 -- synchroized
private synchronized SigleTon05 getInstance(){
if(sigleTon==null){
return new SigleTon05();
}
return sigleTon;
}
}
class SigleTon06 {
// volatile在這裏防止重排序。防止第二個線程拿到第一個線程生成的不完整的對象。
// 對象實例化的操作分爲:分配內存空間、初始化成員變量、引用指向內存。
// 第二、三步可能被指令重排,導致併發來的另一個線程拿到一個沒有初始化成員變量的對象,造成錯誤。
volatile SigleTon06 sigleTon;
// 5、餓漢模式 -- 雙重校驗鎖
private synchronized SigleTon06 getInstance(){
if(sigleTon==null){
synchronized ( SigleTon.class ){ // 類鎖
if( sigleTon == null ) return new SigleTon06();
}
}
return sigleTon;
}
}