Java代碼優(yōu)化總結(jié)(1)

寫在之前

最近,進行了不少代碼的優(yōu)化的部分熊杨。免得以后忘記,在這里分享給大家盗舰,希望對大家能有點微不足道的幫助晶府!

正文內(nèi)容

  1. JSON對象解析的過程中要盡量避免多次解析的情況;如非必要钻趋,盡量減少JSON對象的反復(fù)解析川陆。

  2. 使用Redis或數(shù)據(jù)庫查詢時,如果是上下文有邏輯關(guān)系的代碼蛮位,盡量避免反復(fù)使用同一查詢较沪,原則是:能少查一次就少查一次。查詢結(jié)果建議都要進行一定的非空或其它異常判斷等等失仁。

  3. 在進行業(yè)務(wù)邏輯的計算和IO讀寫操作時购对,建議分別使用不同的線程骡苞。例如:業(yè)務(wù)邏輯的計算可以使用CPU密集型線程池贴见;而IO操作可以使用IO型線程霜定。RxJava是一個不錯的選擇工具辖所,值得嘗試!

  4. 使用重試邏輯時,不要太暴力。
    如下圖肆糕,Redis有可能會出現(xiàn)超時的情況浑玛,這里的業(yè)務(wù)又比較重要,所以有必要加上重試邏輯,而加的重試邏輯又太過暴力了俄周。


    Paste_Image.png

這樣可能得不到想要的效果排龄,反而會加重Redis的負(fù)擔(dān),建議加上適當(dāng)?shù)耐nD時間。如下圖:


Paste_Image.png
  1. 查詢數(shù)據(jù)庫或Redis等等時流译,應(yīng)該盡可能給予返回值驹马,前后代碼有先后依賴關(guān)系時,應(yīng)該給予必要的邏輯判斷。盡量不要像下面這樣阎肝,insert進去數(shù)據(jù)庫之后就什么不管了。因為insert操作會可能失敗的,一旦這里失敗引镊,其它有依賴的地方就會產(chǎn)生問題,代碼要盡量能考慮到失敗時的處理篮条。


    Paste_Image.png
  2. 應(yīng)當(dāng)盡量避免大量Redis Key同時(分毫不差的)失效弟头。Redis是單線程模型的,如果大量對象同時失效涉茧,后續(xù)的請求可能會頻繁出現(xiàn)請求超時的問題赴恨。如下圖:


    Paste_Image.png

優(yōu)化方案是:可以在失效時間的后邊加上所能容許的隨機時間。如下圖:


Paste_Image.png
  1. Redis要盡量使用池的方式伴栓,應(yīng)該避免使用直連的方式伦连。直接的方式每次都會建立一次TCP連接,而池的方式可以減少TCP連接次數(shù)钳垮,減少TCP握手時間惑淳,提高響應(yīng)速度。 如此類推饺窿,凡是建立對象比較耗時的地方歧焦,都可以適當(dāng)考慮對象池技術(shù)。推薦Common-pool2工具肚医,使用起來較簡單绢馍,不用自己實現(xiàn)。

  2. 如果使用雙重檢查的方式實現(xiàn)單例時肠套,記得加上volatile關(guān)鍵字舰涌。因為由于編譯器可能會重排序我們的代碼,會導(dǎo)致雙重檢查的編譯結(jié)果和源碼不一致你稚,多線程調(diào)用時也可能會有線程安全問題瓷耙,而volatile可以幫忙我們避免編譯器的重排序。


    Paste_Image.png

使用volatile時應(yīng)該注意入宦,該關(guān)鍵字只能保證數(shù)據(jù)的可見性哺徊。只有在狀態(tài)真正獨立于程序內(nèi)其他內(nèi)容時才能使用 volatile 。 推薦閱讀這篇關(guān)于volatile的文章:http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

  1. 對于頻繁操作Redis時乾闰,如果各個操作之間沒有先后聯(lián)系落追,又不用考慮及時返回的結(jié)果,應(yīng)當(dāng)盡量使用pipline的方式來提高效率涯肩。如下圖的使用方式:


    Paste_Image.png

如下圖轿钠,可以使用pipline的方式提高效率:


Paste_Image.png

pipline能 幫忙我們批量處理命令巢钓,一次性返回操作結(jié)果,減少TCP交互次數(shù)疗垛,提高效率症汹。但是,pipline的方式不能過度使用贷腕,pipline會把Redis的操作結(jié)果緩存到內(nèi)存中背镇,然后一次性返回給客戶端,pipline的方式依賴內(nèi)存的限制泽裳,操作結(jié)果集盡量不要過大瞒斩。

  1. 使用Redis的鎖機制的時候,應(yīng)當(dāng)仔細(xì)考慮使用的范圍和方式涮总。
    如下圖胸囱,此代碼使用key的存在與否和是否為1來保證原子性操作。但是瀑梗,此代碼仍然不能保證多線程安全問題烹笔。假如有兩個線程A和B,同時進入了isExist的邏輯抛丽,而A線程獲得CPU的資源較早谤职,處理的速度較快,A線程走完整個方法的邏輯時铺纽,B線程仍然在原始位置柬帕。此時哟忍,B線程才獲取CPU資源走下面的邏輯狡门,就會出現(xiàn)數(shù)據(jù)重復(fù)插入的問題。


    Paste_Image.png

a. 優(yōu)化的方式是可以把ret=xxx這行代碼移到if(!isExist...)上面锅很,而if語句里面的查詢等操作也可以提到if的上面其馏,盡可能的減少此原子操作的時間。
b. 也可以使用Redis樂觀鎖的方式來保證原子性操作爆安。關(guān)于Redis樂觀鎖(CAS)的實現(xiàn)方式叛复,請自行Google!

  1. 使用Kafka時扔仓,生產(chǎn)者和消費者建議使用批量的方式來提高吞吐量褐奥,而批量失敗的后果也要進行考慮,批量失敗對結(jié)果的影響肯定要比單一生產(chǎn)或消費大很多翘簇。不是特別建議使用下面的這種方式撬码,雖然程序可以正常跑,但是每次遇到Kafka隊列里有大量數(shù)據(jù)積累時都是加機器的方式解決版保。其實完全可以從代碼角度進行優(yōu)化呜笑,減少機器的使用夫否,提高單機的CPU和內(nèi)存使用率。


    Paste_Image.png
  2. 使用線程池時要注意選擇適當(dāng)?shù)木芙^策略叫胁。
    如下圖凰慈,handle方法是在死循環(huán)中被調(diào)用的,所以創(chuàng)建Runnable任務(wù)的速度是非惩斩欤快的微谓,優(yōu)化之前的代碼是沒有拒絕策略的,也就是使用的默認(rèn)策略输钩。下圖是優(yōu)化過的代碼堰酿,之前是沒有第一塊紅色區(qū)域的代碼的。


    Paste_Image.png

如下圖张足,從JDK源碼中可以看出触创,線程池處理不了的任務(wù)是放在無界隊列(LinkedBlockingQueue的size=Integer.MAX_VALUE)中的,而這樣就有一個很大的問題为牍。如果消費的速度跟不上哼绑,內(nèi)存中就積累了大量的Task,內(nèi)存使用率會急速上高碉咆。所以為線程池任務(wù)的存放選擇一個合適的拒絕策略就很有必要了抖韩。


Paste_Image.png

如本問題的第一張圖中的第一塊代碼,如果發(fā)生拒絕疫铜,會執(zhí)行executor.getQueue().put(r); 而put是阻塞式的茂浮,會一直等待Queue中有可用空間為止,而被阻塞的線程就是放入Task的線程壳咕,也就是調(diào)用handle的線程席揽,這樣就不會導(dǎo)致Queue無限增大了。

寫在之后

 寫著寫著就中午了谓厘,該吃飯了... 下次接著分享... 歡迎批評指正幌羞,交流學(xué)習(xí)!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末竟稳,一起剝皮案震驚了整個濱河市属桦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌他爸,老刑警劉巖聂宾,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诊笤,居然都是意外死亡系谐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進店門盏混,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔚鸥,“玉大人惜论,你說我怎么就攤上這事≈古纾” “怎么了馆类?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弹谁。 經(jīng)常有香客問我乾巧,道長,這世上最難降的妖魔是什么预愤? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任沟于,我火速辦了婚禮,結(jié)果婚禮上植康,老公的妹妹穿的比我還像新娘旷太。我一直安慰自己,他們只是感情好销睁,可當(dāng)我...
    茶點故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布供璧。 她就那樣靜靜地躺著,像睡著了一般冻记。 火紅的嫁衣襯著肌膚如雪睡毒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天冗栗,我揣著相機與錄音演顾,去河邊找鬼。 笑死隅居,一個胖子當(dāng)著我的面吹牛钠至,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播军浆,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼棕洋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乒融?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤摄悯,失蹤者是張志新(化名)和其女友劉穎赞季,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奢驯,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡申钩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瘪阁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撒遣。...
    茶點故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡邮偎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出义黎,到底是詐尸還是另有隱情禾进,我是刑警寧澤,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布廉涕,位于F島的核電站泻云,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏狐蜕。R本人自食惡果不足惜宠纯,卻給世界環(huán)境...
    茶點故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望层释。 院中可真熱鬧婆瓜,春花似錦、人聲如沸贡羔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽治力。三九已至蒙秒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宵统,已是汗流浹背晕讲。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留马澈,地道東北人瓢省。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像痊班,于是被迫代替她去往敵國和親勤婚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,813評論 25 707
  • 從三月份找實習(xí)到現(xiàn)在涤伐,面了一些公司馒胆,掛了不少,但最終還是拿到小米凝果、百度祝迂、阿里、京東器净、新浪型雳、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,216評論 11 349
  • 時間之尺 一個人如何對待他的時間,決定了他可以成為什么樣的人纠俭。 1沿量、對待時間,應(yīng)該學(xué)習(xí)孩子“鄭重”的態(tài)度冤荆。 鄭重是...
    共剪西窗燭閱讀 178評論 0 0
  • 幾乎所有腫瘤的發(fā)病都涉及心理因素匙赞,痛苦的心理可能貫穿腫瘤診斷治療的臨床全過程佛掖,現(xiàn)代醫(yī)學(xué)研究發(fā)現(xiàn)精神狀態(tài)和機體免疫功...
    訴說心里想過的事情閱讀 410評論 0 0
  • 今天是農(nóng)歷的小年,恰巧公司舉辦了2016年的年會涌庭,算是給我的2016舉辦了一個儀式芥被,我將我生命中的唯一一個2...
    佐小七閱讀 149評論 0 0