本文屬于系列文章《設(shè)計(jì)模式》疗韵,附上文集鏈接
單例模式定義
- 確保對(duì)象在內(nèi)存中有且只有一個(gè)权薯,并自行實(shí)例化為系統(tǒng)提供這個(gè)實(shí)例嗓化。
- 這個(gè)模式在我們只需要一個(gè)創(chuàng)建一個(gè)對(duì)象,避免重復(fù)創(chuàng)建對(duì)象的時(shí)候使用搅方,比如說配置文件比吭,工具類,緩存姨涡,線程池衩藤,日志對(duì)象等等
- 單例模式屬于創(chuàng)建類模式
實(shí)現(xiàn)方式一 餓漢模式
//1.將構(gòu)造函數(shù)私有化
private SingleTon(){ }
//2、內(nèi)部調(diào)用構(gòu)造函數(shù)創(chuàng)建對(duì)象涛漂,對(duì)象聲明為私有屬性
// (餓漢模式的命名由此而來赏表,因?yàn)镾ingleTon對(duì)象是static的检诗,在加載SingleTon類的時(shí)候,instance對(duì)象就會(huì)被創(chuàng)建瓢剿,無論有沒有使用該對(duì)象逢慌,都會(huì)創(chuàng)建對(duì)象,就像餓漢去餐廳吃飯间狂,無論吃不吃攻泼,先點(diǎn)了再說 )
// final關(guān)鍵字確保該實(shí)例對(duì)象是內(nèi)存中有且只有一個(gè)
private final static SingleTon instance = new SingleTon();
//3、提供方法獲取singleTon實(shí)例
public static SingleTon getInstance(){
return instance;
}
分析
將實(shí)例聲明為static屬性鉴象,在類被加載的時(shí)候就會(huì)創(chuàng)建實(shí)例忙菠,final屬性確保了對(duì)象的唯一性。
實(shí)現(xiàn)方式二 懶漢模式
//1.將構(gòu)造函數(shù)私有化
private SingleTon(){ }
// 2.2纺弊、聲明一個(gè)SingleTon對(duì)象牛欢,注意,是聲明
private static SingleTon instance = null;
//3俭尖、提供方法獲取singleTon實(shí)例
public static SingleTon getInstance(){
return instance;
}
分析
這個(gè)一般叫做懶漢模式氢惋,因?yàn)槭菓屑虞d嘛洞翩,只有對(duì)象要被使用的時(shí)候才會(huì)實(shí)例化,但是這里就有一個(gè)問題了稽犁,假設(shè)在多線程的情況下,就會(huì)容易會(huì)創(chuàng)建多個(gè)實(shí)例骚亿,這不符合單例模式的定義已亥,所以修改下
絕對(duì)安全的懶漢模式
//1.將構(gòu)造函數(shù)私有化
private SingleTon(){ }
// 2.2、聲明一個(gè)SingleTon對(duì)象来屠,注意虑椎,是聲明
private static SingleTon instance = null;
// 3 在之前的基礎(chǔ)上增加了synchronized關(guān)鍵字和一個(gè)instance判空
public static synchronized SingleTon getInstance(){
if(instance == null){
Thread.sleep(1000);
instance = new SingleTon();
}
return instance;
}
單例模式擴(kuò)展:指定數(shù)量的對(duì)象
哈哈,在書上看到的俱笛,雖然不知道能不能用上捆姜,但是當(dāng)做活躍下思維吧,覺得挺好玩的迎膜。
// 單例類
public class Singleton {
private Singleton(String name){
nameList.add(name);
}
// 對(duì)象的最大個(gè)數(shù)
private static int maxNumOfSingleton = 3;
//定義對(duì)象列表
private static ArrayList<Singleton> singletonList = new ArrayList<Singleton>();
// 定義對(duì)象的名字列表泥技,方便知道是哪個(gè)對(duì)象
private static ArrayList<String > nameList = new ArrayList<>();
//當(dāng)前對(duì)象的序號(hào)
private static int countNum;
static{
// 實(shí)例化
for(int i = 1;i<=maxNumOfSingleton;i++){
singletonList.add(new Singleton(i +"號(hào)對(duì)象"));
}
}
public static Singleton getInstance(){
countNum = new Random().nextInt(maxNumOfSingleton);
return singletonList.get(countNum);
}
public void say(){
System.out.println("我是"+nameList.get(countNum));
}
}
// 場(chǎng)景
public class Client {
public static void main(String[] args) {
for(int i =0;i<5;i++){
Singleton.getInstance().say();
}
}
}
結(jié)果:
我是3號(hào)對(duì)象
我是3號(hào)對(duì)象
我是1號(hào)對(duì)象
我是2號(hào)對(duì)象
我是1號(hào)對(duì)象
以上就是單例模式