hello,大家好,這裏是布丁薩瑪,最近疫情結束了。小夥伴們是不是都要和自己的女朋友出去嗨了?
什麼?
你還沒有朋友
。
不要緊,今天布丁就教你寫個女朋友。
開始搞事情!!
幾天前,我有一個朋友,是一個單身貴族
。並且單身了18年了。有一天他就跑來找我說。
“布丁啊,你說JAVA既然可以把任何東西都抽象成一個對象
,那麼是不是可以寫個女朋友出來”。
“嗯!!我覺得可以有,騷年。去吧勇敢的去創造奇蹟吧”
於是過了十分鐘朋友拿着他寫的女朋友來找我了。
“布丁,布丁你看看這就是我寫的女朋友。”
“我的女朋友可以和我一起逛街、喫飯、看電影。甚至之後的嘿嘿嘿
”
布丁:“嗯?,嘿嘿嘿是什麼啊?我懷疑你在搞黃色。”
“什麼?什麼是搞黃色?嘿嘿嘿是我們兩個一起在房間裏講笑話。所以纔會有嘿嘿嘿的聲音”
哦哦哦。。。原來如此(奇怪的只是增加了)。
你們這羣心裏有顏色的人是不是想歪了。想歪了評論區罰站去。
下面我們看下我朋友寫的女朋友。
/**
* @Author: buding
* 女朋友類
*
* @DateTime: 2020/6/8 8:52 下午
*/
public class Girl {
// 好感度
private int favorability = 0;
/**
* 逛街
*/
public void shop() {
System.out.println("你和女朋友一起去看逛街,好感度+30");
// 好感度+30
favorability += 30;
showFavorability();
}
/**
* 喫飯
*/
public void eat() {
System.out.println("你和女朋友一起去看喫飯,好感度+30");
favorability += 30;
showFavorability();
}
/**
* 看電影
*/
public void watchMovie() {
System.out.println("你和女朋友一起去看電影,好感度+30");
favorability += 30;
showFavorability();
}
/**
* 嘿嘿嘿
*/
public void heiheihei() {
if (favorability > 90) {
System.out.println("晚上等你一起heiheihei");
} else {
System.out.println("警察叔叔!!!!!這有個變態");
}
}
private void showFavorability() {
System.out.println("你和你女朋友的好感度是:" + favorability);
}
}
看完上面的女朋友。
有很多小夥伴就說了是不是可以直接嘿嘿嘿啊?
哎,我就不知道了。笑話有這麼好聽嗎?逛街不好嗎?
搞不懂你們。
不過,這裏如果我們想要和女朋友嘿嘿嘿。那麼就首先要把好感度達到一定的90以上。
那麼要怎麼樣才能達到那?
我們可以陪女朋友逛街、喫飯、看電影
。這樣好感度就會達到100 。
我們就可以和女朋友嘿嘿嘿了。
ok,簡單。
那麼我們開始吧。
public static void main(String[] args) {
Girl girl = new Girl();
// 逛街
girl.shop();
// 喫飯
girl.eat();
// 看電影
girl.watchMovie();
}
我們已經和女朋友逛了街、吃了羊腰子、看了愛情電影。就在你想着要和女朋友開個房間一起講笑話的時候。
女朋友突然說:人家想要在五星級酒店的總統
套房裏面講笑話。
於是你看了看你支付寶僅有的150塊錢。
愣在了原地。
你看着你女朋友說:寶貝,你可以等我嗎?我一定要和你在五星級酒店的總統套房裏面講笑話。不過我現在沒有錢。我要去北京搬磚。努力賺錢,
十年~十年~十年
之後我來接你去五星級酒店講笑話。
女朋友說:好,我會等你的。。你去吧。【哭泣
於是你開始了十年的打工之路~~~
~~~十年之後~~~
你望着你手裏搬了十年磚終於攢夠的10000塊錢。
今天終於可以和女朋友一起去五星級酒店總統套房講笑話了。
於是你興沖沖的詢問女友要不要嘿嘿嘿。
Girl girl = new Girl();
girl.heiheihei();
然而,你得到的回答是
oh,天吶?爲什麼?爲什麼?爲什麼會這樣。我苦苦搬磚十年。爲什麼她還是不願意和我去講笑話。明明~~明明我們都已經經歷了那麼多。
爲什麼啊?老天爺你告訴我啊!!!
這是天上一道金燦燦的光芒照在了你的面前。
一個白髮蒼蒼的老爺爺來到了你的面前。
“少年啊,你是不是覺得你的女朋友變了?”
“是啊?爲什麼啊?”
“哎,他已經不是你的女朋友了。因爲你沒有用單例,所以你每一次創建的女朋友的是不同的女朋友”
“那什麼是單例我要怎麼使用單例!!!告訴我啊!!”
“騷年,彆着急,接下來我們娓娓道來”
正文開始
什麼是單例模式?
看完上面的慘劇,我們就知道了爲了能夠和女朋友嘿嘿嘿,我們是一定要使用單例的。
如果不實用單例,那麼我們每一次都要和女朋友先逛街、喫飯、看電影
。才能嘿嘿嘿。
如果使用單例,那麼我們就可以只陪她做一次之後,之後的時間就可以隨時和她講笑話了。
是不是很開心?很興奮?
那麼什麼是單例模式呢?
單例就是讓我們自己只有一個女朋友。而且隨時都可以調用。
“布丁布丁,我喜歡多人運動。“
那麼單例模式的簡單的定義就是:只存在一個實例,並且提供一個全局調用的方法
簡單吧。不難吧。那麼接下來我們就來看下,我們要如何實現單例。又有幾種實現單例的方法呢。
單例模式的5種寫法
以下是實現單例的常用的幾種方法,我個人感覺沒有絕對最優的方法,至於最終使用哪一種還要看項目的需求。
ok,廢話少說,我們一起來看看吧。
1、懶漢法
懶顧名思義就是實例在用到的時候纔去創建,“比較懶”,用的時候纔去檢查有沒有實例,如果有則返回,沒有則新建。
優點:寫起來簡單,容易理解
缺點:線程不安全
/**
* @Author: buding
* 懶漢式
* @DateTime: 2020/6/8 12:45 下午
*/
public class Lhan {
private static Lhan instance = null;
// 將構造方法私有化,防止外部調用
private Lhan() {
System.out.println("創建了Lhan");
}
// 使用static使外部可以直接進行調用。
public static Lhan getInstance() {
// 判斷是不是有實例化過,沒有則進行實例話,否則直接返回實例化後的對象
if (instance == null) {
instance = new Lhan();
}
return instance;
}
}
2、餓漢法
餓漢式,從名字上也很好理解,就是“比較勤”,由於使用了static
關鍵字,所以實例在初始化的時候就已經建好了,不管你有沒有用到,都先建好了再說。
優點:書寫簡單、沒有線程安全的問題
缺點:是浪費內存空間
public class Ehan {
private static final Ehan instance = new Ehan();
public Ehan() {
System.out.println("創建了Ehan");
}
public static Ehan getInstance() {
return instance;
}
}
2、雙檢鎖
雙檢鎖,又叫雙重校驗鎖,綜合了懶漢式和餓漢式兩者的優缺點整合而成。看上面代碼實現中,特點是在synchronized關鍵字內外都加了一層 if 條件判斷,這樣既保證了線程安全,又比直接上鎖提高了執行效率,還節省了內存空間。
記得要加上volatile
關鍵字,因爲instance = new DoubleCheck();
並不是一步完成的。如果不加volatile
,多線程容易出現指令重排
的問題。
指令重排
:在計算機執行指令的順序在經過程序編譯器編譯之後形成的指令序列,一般而言,這個指令序列是會輸出確定的結果;以確保每一次的執行都有確定的結果。但是,一般情況下,CPU和編譯器爲了提升程序執行的效率,會按照一定的規則允許進行指令優化。
優點:沒有線程安全的問題
缺點:書寫麻煩
/**
* @Author: buding
* 雙重鎖
* @DateTime: 2020/6/8 1:01 下午
*/
public class DoubleCheck {
private static volatile DoubleCheck instance = null;
private DoubleCheck() {
System.out.println("創建了DoubleCheck");
}
public static DoubleCheck getInstance() {
if (instance == null) {
synchronized (DoubleCheck.class) {
if (instance == null) {
instance = new DoubleCheck();
}
}
}
return instance;
}
}
2、靜態內部類
靜態內部類主要是利用了JVM自身的特性。帶有static
關鍵字只在類加載的是有執行一次,所以不會多次創建。
優點:書寫簡單 無多線程問題
缺點:只適用於靜態域情況
/**
* @Author: buding
* 靜態內部類
* @DateTime: 2020/6/8 1:04 下午
*/
public class StaticClass {
private StaticClass() {
System.out.println("創建了StaticClass");
}
private static class Holder {
private static StaticClass instance = new StaticClass();
}
public static StaticClass getInstance() {
return Holder.instance;
}
}
2、枚舉
枚舉的方式是比較少見的一種實現方式,也是利用了JVM自身的特性,防止多次實例化。
優點:書寫簡單
缺點:不好理解 無法傳遞初始化參數
/**
* @Author: 於丁
* @DateTime: 2020/6/8 1:27 下午
*/
public enum Enums {
INSTANCE;
private EnumDemo enumDemo = new EnumDemo();
public EnumDemo getEnumDemo() {
return enumDemo;
}
}
後記
之後把這些東西和我的那個朋友講了之後他也順利的寫出來單例模式的女朋友。
並且也成功和她去五星級總統套房講笑話去了。
代碼如下
/**
* @Author: buding
* 女朋友單例版(靜態內部類)
* @DateTime: 2020/6/8 8:52 下午
*/
public class GirlSignleton {
private static GirlSignleton instance;
// 好感度
private int favorability = 0;
private GirlSignleton() {
shop();
eat();
watchMovie();
}
private static class Holder {
private static GirlSignleton girlSignleton = new GirlSignleton();
}
public static GirlSignleton getInstance() {
return Holder.girlSignleton;
}
/**
* 逛街
*/
public void shop() {
System.out.println("你和女朋友一起去看逛街,好感度+30");
// 好感度+30
favorability += 30;
showFavorability();
}
/**
* 喫飯
*/
public void eat() {
System.out.println("你和女朋友一起去看喫飯,好感度+30");
favorability += 30;
showFavorability();
}
/**
* 看電影
*/
public void watchMovie() {
System.out.println("你和女朋友一起去看電影,好感度+30");
favorability += 40;
showFavorability();
}
/**
* 嘿嘿嘿
*/
public void heiheihei() {
if (favorability > 90) {
System.out.println("晚上等你一起heiheihei");
} else {
System.out.println("警察叔叔!!!!!這有個變態");
}
}
private void showFavorability() {
System.out.println("你和你女朋友的好感度是:" + favorability);
}
}
ok,今天的單例模式就到這裏了,最終我們使用了靜態內部類的方式實現了單例的女朋友。 小夥伴們可以試着使用其他的模式寫一下自己的女朋友。如果有什麼問題歡迎評論區指出。謝謝
🙏