




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、目錄前言1一、編程規約2(一)(二)(三)(四)(五)(六)(七)(八)(九)命名規約2定義4格式規約5OOP 規約7集合處理11并發處理13語句16注釋規約17其它18二、異常日志20(一)(二)異常處理20日志規約21三、MySQL 規約23(一)(二)(三)(四)建表規約23索引規約25SQL 規約27ORM 規約28四、工程規約29(一)(二)(三)應用分層29二方庫規約30服務器規約32五、安全規約33附 1:版本歷史34附 2:本規約專有名詞34附 3:法律 34(注:全文瀏覽時請使用 PDF 左側導航欄) 阿里巴巴 Java 開發手冊前言阿里巴巴Java 開發手冊是阿里巴巴集團技
2、術團隊的集體經驗總結,經歷了多次大規模一線實戰的檢驗及不斷的完善,反饋給廣大開發者。現代行業的高速發展對于開發者的綜合素質要求越來越高,因為不僅是編程知識點,其它維度的知識點也會影響到的最終交付質量。比如:數據庫的表結構和索引設計缺陷可能帶來上的架構缺陷或性能風險;工程結構混亂導致維護;沒有鑒權的漏洞代碼被等等。所以本手冊以 Java 開發者為中心視角,劃分為編程規約、異常日志規約、MySQL 規約、工程規約、安全規約五大塊,再根據內容特征,細分成若干二級子目錄。根據約束力強弱及故障敏感性,規約依次分為強制、推薦、參考三大類。對于規約里的內容,“說明”對內容做了引申和解釋;“正例”提倡什么樣的
3、編碼和實現方式;“反例”說明需要提防的雷區,以及真實的錯誤案例。本手冊的愿景是碼出質量、碼出高效。代碼的字里行間流淌的是生命中的血液,質量的提升是盡可能少踩坑,杜絕踩重復的坑,切實提升質量意識。另外,現代架構都需要協同開發完成,高效考慮的是降低協同成本,所謂無規矩不成方圓,無規范不能協作。眾所周知,制訂交通法規表面上是要限制行車權,實際上是保障公眾的人身安全。試想如果沒有限速,沒有紅綠燈,沒有規定靠右行駛,誰還敢上路行駛。對來說,適當的規范和標準絕不是消滅代碼內容的創造性、優雅性,而是限制過度個性化,以一種普遍認可的統一方式一起做事,提升協作效率。阿里巴巴Java 開發手冊,開放包容地認真總結
4、社區、博客、論壇的反饋,及時,保持與時俱進。請關注手冊末頁的“阿里技術”和“云棲社區”公眾號獲取最新版。1 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊Java 開發手冊一、編程規約(一) 命名規約1. 【強制】 代碼中名均不能以下劃線或符號開始,也不能以下劃線或符號結束。反例: _name / name / $Object / name_ / name$ / Object$2. 【強制】 代碼中名嚴禁使用拼音與英文混合的方式,更不直接使用中文的方式。說明:正確的英文拼寫和語法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式也要避免采用。反例: DaZhePromotion
5、 打折 /fenByName() 評分 / int 某變量 = 3get正例: alibaba / youku / hangzhou 等國際通用的名稱,可視同英文。3. 【強制】類名使用 UpperCamelCase 風格,必須遵從駝峰形式,但以下情形例外:(領域模型的相關命名)DO / BO /DTO / VO 等。正例:MarcoPolo /反例:macroPolo /UserDO /UserDo /XmlService /XMLService /TcpUdpDeal / TaPromotionTCPUDPDeal / TAPromotion4. 【強制】名、參數名、成員變量、局部變量都統
6、一使用 lowerCamelCase 風格,必須遵從駝峰形式。正例: localValue / getHttpMessage() / inputUserId5. 【強制】命名全部大寫,單詞間用下劃線隔開,力求語義表達完整清楚,不要嫌名字長。正例: MAX_STOCK_COUNT反例: MAX_COUNT6. 【強制】抽象類命名使用 Abstract 或 Base 開頭;異常類命名使用 Exception 結尾;測試類命名以它要測試的類的名稱開始,以 Test 結尾。7. 【強制】中括號是數組類型的一部分,數組定義如下:String args;反例:使用 String args的方式來定義。2
7、/ 37用于商業用途,違者版本號制定團隊更新日期備注1.1.0阿里巴巴集團技術團隊2017.2.27增加前言和專有名詞說明部分描述。 阿里巴巴 Java 開發手冊8. 【強制】POJO 類中類型的變量,都不要加 is,否則部分框架會引起序列化錯誤。也是 isSuccess(),RPC反例:定義為基本數據類型 Boolean isSuccess;的屬性,它的框架在反向的時候,“以為”對應的屬性名稱是 success,導致屬性獲取不到,進而拋出異常。9. 【強制】統一使用小寫,點分隔符之間有且僅有一個自然語義的英語單詞。統一使用單數形式,但是類名如果有復數含義,類名可以使用復數形式。正例: 應用工
8、具類為 com.alibaba.open.util、類名為 MessageUtils(此規則參考spring 的框架結構)10. 【強制】杜絕完全不規范的縮寫,避免不知義。反例: AbstractClass“縮寫”命名成 AbsClass;condition“縮寫”命名成 condi,此類隨意縮寫嚴重降低了代碼的可閱讀性。11. 【推薦】如果使用到了設計模式,建議在類名中體現出具體模式。說明:將設計模式體現在名字中,有利于閱讀者快速理解架構設計思想。正例:public class OrderFactory;public class LoginProxy;public class Resourc
9、eObserver;12. 【推薦】接口類中的和屬性不要加任何修飾符號(public 也不要加),保持代碼的簡潔性,并加上有效的 Javadoc 注釋。盡量不要在接口里定義變量,如果一定要定義變量,肯定是與接口相關,并且是整個應用的基礎。正例:接口簽名:void f();接口基礎表示:String COMPANY = "alibaba"反例:接口定義:public abstract void f();說明:JDK8 中接口認實現。有默認實現,那么這個 default,是對所有實現類都有價值的默13. 接口和實現類名有兩套規則:1) 【強制】對于 Service 和 DAO
10、類,基于 SOA 的理念, 的實現類用 Impl 的后綴與接口區別。正例:CacheServiceImpl 實現 CacheService 接口。2) 【推薦】 如果是形容能力的接口名稱,取對應的形容詞做接口名(通常是able 的形式) 。正例:AbstractTranslator 實現 Translatable。出來的服務一定是接口,內部14. 【參考】枚舉類名建議帶上 Enum 后綴,枚舉成員名稱需要寫,單詞間用下劃線隔開。說明:枚舉其實就是特殊的類,且構造被默認強制是私有。正例:枚舉名字:DealStatusEnum,成員名稱:SUCCESS / UNKOWN_REASON。3 / 37
11、用于商業用途,違者 阿里巴巴 Java 開發手冊15. 【參考】各層命名規約:Service/DAO 層A)命名規約1)2)3)4)5)6)獲取單個對象的用 get 做前綴。獲取多個對象的用 list 做前綴。獲取統計值的用 count 做前綴。的刪除的修改的用 save(推薦)或 insert 做前綴。用 remove(推薦)或 delete 做前綴。用 update 做前綴。B)領域模型命名規約1)2)3)4)DO,數據對象:即為數據表名。數據傳輸對象:DTO,展示對象:VO,為業務領域相關的名稱。為網頁名稱。POJO 是 DO/DTO/BO/VO 的統稱,POJO。命名成(二)定義1.
12、【強制】不出現任何魔法值(即定義的)直接出現在代碼中。反例: String key = "Id#cache.put(key, value);_"+tradeId;2. 【強制】long 或者 Long 初始賦值時,必須使用大寫的 L,不能是小寫的 l,小寫容易跟數字1,造成誤解。說明:Long a = 2l; 寫的是數字的 21,還是 Long 型的 2?3. 【推薦】不要使用一個類維護所有,應該按功能進行歸類,維護。如:緩存相關的放在類:CacheConsts 下;系統配置相關的放在類:ConfigConsts 下。說明:大而全的類,非得使用查找功能才能定位到修改的,不利
13、于理解和維護。4. 【推薦】內共享的復用層次有五層:跨應用共享、應用內共享、子工程內共享、包、類內共享。1)2).jar 中的 constant 目錄下。跨應用共享應用內共享:放置在二方庫中,通常是:放置在一方庫的 modules 中的 constant 目錄下。反例:易懂變量也要統一定義成應用內共享“是”的變量:類 A 中:public static final String類 B 中:public static final String,兩位攻城兩個類中分別定義了表示YES = "yes"YES = "y"A.YES.equals(B.YES),預期
14、是 true,但實際返回為 false,導致產生線上問題。4 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊3)4)5)子工程內部共享:即在當前子工程的 constant 目錄下。:即在當前包下單獨的 constant 目錄下。:直接在類內部 private static final 定義。包內共享類內共享5. 【推薦】如果變量值僅在一個范圍內變化用 Enum 類。如果還帶有名稱之外的延伸屬性,必須使用 Enum 類,下面正例中的數字就是延伸,表示星期幾。正例:public Enum MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4),
15、FRIDAY(5), SATURDAY(6),SUNDAY(7);(三) 格式規約1. 【強制】大括號的使用約定。如果是大括號內為空,則簡潔地寫成即可,不需要換行;如果是非空代碼塊則:1)2)3)4)左大括號前不換行。左大括號后換行。 右大括號前換行。右大括號后還有 else 等代碼則不換行;表示終止右大括號后必須換行。2. 【強制】 左括號和后一個字符之間不出現空格;同樣,右括號和前一個字符之間也不出現空格。詳見第 5 條下方正例提示。3. 【強制】if/for/while/switch/do 等保留字與左右括號之間都必須加空格。4. 【強制】任何運算符左右必須加一個空格。說明:運算符賦值運
16、算符=、邏輯運算符&&、加減乘除符號、三目運算符等。5. 【強制】縮進采用 4 個空格,使用 tab 字符。說明:如果使用 tab 縮進,必須設置 1 個 tab 為 4 個空格。IDEA 設置 tab 為 4 個空格時, 勾選 Use tab character;而在 eclipse 中,必須勾選 insert spaces for tabs。正例: (涉及 1-5 點)public static void main(String args) / 縮進 4 個空格String say = "hello"/ 運算符的左右必須有一個空格int flag = 0
17、;/if 與括號之間必須有一個空格,括號內的 f 與左括號,0 與右括號不需要空格if (flag = 0) System.out.println(say);/ 左大括號前加空格且不換行;左大括號后換行if (flag = 1) System.out.println("world");/ 右大括號前換行,右大括號后有 else,不用換行5 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊 else System.out.println("ok");/ 在右大括號后直接結束,則必須換行6. 【強制】單行字符數限制不超過 120 個,超出需要換行,換
18、行時遵循如下原則:1)2)3)4)5)第二行相對第一行縮進 4 個空格,從第三行開始,不再繼續縮進,參考示例。運算符與下文一起換行。調用的點符號與下文一起換行。在多個參數超長,逗號后進行換行。在括號前不要換行,見反例。正例:StringBuffer sb = new StringBuffer();/超過 120 個字符的情況下,換行縮進 4 個空格,并且sb.append("zi").append("xin").append("huang").append("huang").append("huang&q
19、uot;);前的點符號一起換行反例:StringBuffer sb = new StringBuffer();/超過 120 個字符的情況下,不要在括號前換行sb.append("zi").append("xin").append ("huang");/參數很多的調用可能超過 120 個字符,不要在逗號前換行method(args1, args2, args3, ., argsX);7. 【強制】參數在傳入時,多個參數逗號后邊必須加空格。正例:下例中實參的"a",后邊必須要有一個空格。method("a&
20、quot;, "b", "c");8. 【強制】IDE 的 text file encoding 設置為 UTF-8; IDE 中文件的換行符使用 Unix 格式, 不要使用 windows 格式。9. 【推薦】沒有必要增加若干空格來使某一行的字符與上一行的相應字符對齊。正例:int a = 3; long b = 4L; float c = 5F;StringBuffer sb = new StringBuffer();說明:增加 sb 這個變量,如果需要對齊,則給 a、b、c 都要增加幾個空格,在變量比較多的情況下,是一種累贅的事情。6 / 37用于
21、商業用途,違者 阿里巴巴 Java 開發手冊10. 【推薦】體內的執行語句組、變量的定義語句組、不同的業務邏輯之間或者不同的語義之間一個空行。相同業務邏輯和語義之間不需要空行。說明:沒有必要多行空格進行隔開。(四) OOP 規約1. 【強制】避免通過一個類的對象本,直接用類名來即可。此類的靜態變量或靜態,無謂增加編譯器成2. 【強制】所有的覆寫,必須加Override 注解。反例:getObject()與 get0bject()的問題。一個是字母的 O,一個是數字的 0,加Override可以準確譯報錯。是否覆蓋。另外,如果在抽象類中對簽名進行修改,其實現類會馬上編3. 【強制】相同參數類型,
22、相同業務含義,才可以使用 Java 的可變參數,避免使用 Object。說明:可變參數必須放置在參數列表的最后。(提倡同學們盡量不用可變參數編程)正例:public User getUsers(String type, Integer. ids)4. 【強制】外部正在調用或者二方庫依賴的接口,不修改簽名,避免對接口調用方產生影響。接口過時必須加Deprecated 注解,并清晰地說明采用的新接口或者新服務是什么。5. 【強制】不能使用過時的類或說明:.URLDecoder。中的decode(String encodeStr) 這個已經過時,應該使參數 decode(String source,
23、 String encode)。接口提供方既然明確是過時接口,那么有義務同時提供新的接口;作為調用方來說,有義務去考證過時的新實現是什么。6. 【強制】Object 的 equals equals。正例: "test".equals(object);反例: object.equals("test");說明:推薦使用 java.util.Objects#equals (JDK7 引入的工具類)7. 【強制】所有的相同類型的包裝類對象之間值的比較,全部使用 equals容易拋空指針異常,應使用或確定有值的對象來調用比較。說明:對于 Integer var =
24、 ?在-128 至 127 之間的賦值,Integer 對象是在IntegerCache.cache 產生,會復用已有對象,這個區間內的 Integer 值可以直接使用=進行,但是這個區間之外的所有數據,都會在堆上產生,并復用已有對象,這是一個大坑,推薦使用 equals進行。7 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊8. 關于基本數據類型與包裝數據類型的使用標準如下:1)2)3)【強制】所有的 POJO 類屬性必須使用包裝數據類型。【強制】RPC的返回值和參數必須使用包裝數據類型。【推薦】所有的局部變量使用基本數據類型。說明:POJO 類屬性沒有初值是提醒使用者在需要使用時
25、,必須顯式地進行賦值,任何NPE 問題,或者入庫檢查,使用者來保證。正例:數據庫的結果可能是 null,因為自動拆箱,用基本數據類型接收有 NPE 風險。反例:比如顯示成交總額漲跌情況,即正負 x%,x 為基本數據類型,調用的 RPC 服務,調用不時,返回的是默認值,頁面顯示:0%,這是不合理的,應該顯示劃線-。所以包裝。數據類型的 null 值,能夠表示額外的,如:調用失敗,異常9. 【強制】定義 DO/DTO/VO 等 POJO 類時,不要設定任何屬性默認值。反例:POJO 類的 gmtCreate 默認值為 new Date();但是這個屬性在數據提取沒有置入具體值,在更新其它字段時又附
26、帶更新了此字段,導致創建時間被修改成當前時間。10. 【強制】序列化類新增屬性時,請不要修改 serialVersionUID 字段,避免反序列失敗;如果完全不兼容升級,避免反序列化混亂,那么請修改 serialVersionUID 值。說明:注意 serialVersionUID 不一致會拋出序列化運行時異常。11. 【強制】構造里面加入任何業務邏輯,如果有初始化邏輯,請放在 init中。12. 【強制】POJO 類必須寫 toString。使用 IDE 的中工具:source> generate toString時,如果繼承了另一個 POJO 類,注意在前面加一下 super.toS
27、tring。說明:在查問題。執行拋出異常時,可以直接調用 POJO 的 toString()打印其屬性值,便于排13. 【推薦】使用索引用 String 的 split得到的數組時,需做最后一個分隔符后有無內容的檢查,否則會有拋 IndexOutOfBoundsException 的風險。說明:String str = "a,b,c,"String ary = str.split(",");/預期大于 3,結果是 3 System.out.println(ary.length);14. 【推薦】當一個類有多個構造便于閱讀。,或者多個同名,這些應該按順序放
28、置在一起,8 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊15. 【推薦】 類內。> 私有> getter/setter定義順序依次是:公有或保護說明:公有是類的調用者和維護者最關心的,首屏展示最好;保護雖然只是子類關心,也可能是“模板設計模式”下的;而私有外部不需要特別關心,是一個價值較低,所有 Service 和 DAO 的 getter/setter黑盒實現;因為后。放在類體最16. 【推薦】setter getter/setter反例:中,參數名稱與類成員變量名稱一致,this.成員名 =中,盡量不要增加業務邏輯,增加排查問題的難度。參數名。在public In
29、teger getData() if (true) return data + 100; else return data - 100;17. 【推薦】循環體內,字符串的連接方式,使用 StringBuilder 的 append反例:String str = "start"for (int I = 0; I < 100; i+) str = str + "hello"說明:反編譯出的字節碼文件顯示每次循環都會 new 出一個 StringBuilder 對象,然后進行進行擴展。append 操作,最后通過 toString返回 String 對象
30、,造成內存資源浪費。18. 【推薦】下列情況,成 final 會更有提示性:1)2)3)不需要重新賦值的變量,類屬性、局部變量。對象參數前加 final,表示不修改的指向。類確定不被重寫。19. 【推薦】慎用 Object 的 clone來拷貝對象。說明:對象的 clone的拷貝。默認是淺拷貝,若想實現深拷貝需要重寫 clone實現屬性對象9 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊20. 【推薦】類成員與從嚴:1)2)3)4)5)6)7)8)如果不外部直接通過 new 來創建對象,那么構造必須是 private。工具類不有 public 或 default 構造。類非 sta
31、tic 成員變量并且與子類共享,必須是 protected。類非 static 成員變量并且僅在本類使用,必須是 private。類 static 成員變量如果僅在本類使用,必須是 private。若是 static 成員變量,必須考慮是否為 final。類成員只供類內部調用,必須是 private。類成員只對繼承類公開,那么限制為 protected。說明:任何類、參數、變量,嚴控范圍。過寬泛的范圍,不利于模塊解耦。思考:如果是一個 private 的,想刪除就刪除,一個 public 的 Service,或者一的視個 public 的成員變量,刪除一下,不得手心汗嗎?變量像的小孩,盡量在線
32、內,變量作用域太大,如果的到處跑,那么你會擔心的。10 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊(五) 集合處理1. 【強制】關于 hashCode 和 equals 的處理,遵循如下規則:1) 只要重寫 equals,就必須重寫 hashCode。2) 因為 Set的是不重復的對象,依據 hashCode 和 equals 進行,所以 Set的對象必須重寫這兩個。3) 如果自定義對象做為 Map 的鍵,那么必須重寫 hashCode 和 equals。說明:String 重寫了hashCode 和 equals作為 key 來使用。,所以我們可以非常愉快地使用 String
33、對象2. 【強制】ArrayList 的subList 結果不可強轉成ArrayList,否則會拋出ClassCastException異常:java.util.RandomAccessSubListcannot be cast to java.util.ArrayList ;說明:subList 返回的是 ArrayList 的內部類 SubList,并不是 ArrayList ,而是ArrayList 的一個視圖,對于 SubList 子列表的所有操作最終會反映到原列表上。3. 【強制】 在 subList 場景中,高度注意對原集合元素個數的修改,會導致子列表的遍歷、增加、刪除均產生 Co
34、ncurrentModificationException 異常。4. 【強制】使用集合轉數組的,必須使用集合的 toArray(T array),傳入的是類型完全一樣的數組,大小就是 list.size()。說明:使用 toArray 帶參,入參分配的數組空間不夠大時,toArray內部將重新分配內存空間,并返回新數組地址;如果數組元素大于實際所需,下標為 list.size() 的數組元素將被置為 null,其它數組元素保持個數一致。正例:List<String> list = new ArrayList<String>(2); list.add("gua
35、n");list.add("bao");String array = new Stringlist.size(); array = list.toArray(array);,因此最好將入參數組大小定義與集合元素反例:直接使用 toArray 無參返回值只能是 Object類,若強轉其它問題,此類型數組將出現 ClassCastException 錯誤。5. 【強制】使用工具類 Arrays.asList()把數組轉換成集合時,不能使用其修改集合相關的方法,它的 add/remove/clear會拋出 UnsupportedOperationException 異常
36、。說明:asList 的返回對象是一個 Arrays 內部類,并沒有實現集合的修改。Arrays.asList體現的是適配器模式,只是轉換接口,的數據仍是數組。String str = new String "a", "b" ;List list = Arrays.asList(str);11 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊第一種情況:list.add("c"); 運行時異常。第二種情況:str0 = "gujin" 那么 list.get(0)也會隨之修改。6. 【強制】泛型通配符<
37、;? extends T>來接收返回的數據,此寫法的泛型集合不能使用 add 方法,而<? super T>不能使用 get,做為接口調用賦值時易出錯。說明:擴展說一下 PECS(Producer Extends Consumer Super)原則:1)頻繁往外內容的,適合用上界 Extends。2)經常往里的,適合用下界 Super。7. 【強制】不要在 foreach 循環里進行元素的remove/add 操作。remove 元素請使用 Iterator方式,如果并發操作,需要對 Iterator 對象加鎖。反例:List<String> a = new Ar
38、rayList<String>(); a.add("1");a.add("2");for (String temp : a) if ("1".equals(temp) a.remove(temp);說明:以上代碼的執行結果肯定會出乎大家的意料,那么試一下把“1”換成“2”,會是同樣的結果嗎?正例:Iterator<String> it = a.iterator(); while (it.hasNext() String temp = it.next(); if (刪除元素的條件) it.remove();8.
39、【強制】 在 JDK7 版本及以上,Comparator 要滿足如下三個條件,不然 Arrays.sort, Collections.sort 會報 IllegalArgumentException 異常。說明:1)2)3)x,y 的比較結果和 y,x 的比較結果相反。x>y,y>z,則x>z。x=y,則x,z 比較結果和 y,z 比較結果相同。反例:下例中沒有處理相等的情況,實際使用中可能會出現異常:new Comparator<Override>() public int compare(o1,o2) 1 : -1;return o1.getId() >
40、 o2.getId() ?12 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊9. 【推薦】集合初始化時,盡量指定集合初始值大小。說明:ArrayList 盡量使用 ArrayList(int initialCapacity) 初始化。10. 【推薦】使用 entrySet 遍歷 Map 類集合KV,而不是 keySet 方式進行遍歷。說明:keySet 其實是遍歷了 2 次,一次是轉為 Iterator 對象,另一次是從 hashMap 中取出key 所對應的 value。而 entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是
41、JDK8,使用 Map.foreach。正例:values()返回的是 V 值集合,是一個list 集合對象;keySet()返回的是 K 值集合,是一個 Set 集合對象;entrySet()返回的是 K-V 值組合集合。11. 【推薦】高度注意 Map 類集合 K/V 能不能null 值的情況,如下:反例: 由于 HashMap 的干擾,很多人認為 ConcurrentHashMap 是可以置入 null 值,注意null 值時會拋出 NPE 異常。12. 【參考】合理利用好集合的有序性(sort)和性(order),避免集合的無序性(unsort)和不性(unorder)帶來的影響。說明
42、:有序性是指遍歷的結果是按某種比較規則依次排列的。性指集合每次遍歷的元素次序是一定的。如:ArrayList 是 order/unsort;HashMap 是 unorder/unsort;TreeSet 是order/sort。13. 【參考】利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作,避免使用 List 的contains進行遍歷、對比、去重操作。(六) 并發處理1. 【強制】獲取單例對象需要保證線程安全,其中的也要保證線程安全。說明:資源驅動類、工具類、單例工廠類都需要注意。2. 【強制】創建線程或線程請指定有意義的線程名稱,方便出錯時回溯。正例:public clas
43、s TimerTaskTh public TimerTaskTh() extends Thsuper.setName("TimerTaskTh"); .13 / 37用于商業用途,違者集合類KeyValueSuper說明Hashtable不為 null不為 nullDictionary線程安全ConcurrentHashMap不為 null不為 nullAbstractMap分段鎖技術TreeMap不為 null為 nullAbstractMap線程不安全HashMap為 null為 nullAbstractMap線程不安全 阿里巴巴 Java 開發手冊3. 【強制】線程資
44、源必須通過線程池提供,不在應用中自行顯式創建線程。說明:使用線程池的好處是減少在創建和銷毀線程上所花的時間以及系統資源的開銷,解決資源不足的問題。如果不使用線程池,有可能造成系統創建大量同類線程而導致消耗完內存或者“過度切換”的問題。4. 【強制】線程池不使用 Executors 去創建,而是通過 ThPoolExecutor 的方式,這樣的處理方式讓寫的同學更加明確線程池的運行規則,規避資源耗盡的風險。說明:Executors 返回的線程池對象的弊端如下:1)FixedThPool 和 SingleThPool:的請求隊列長度為 Integer.MAX_VALUE,可能會堆積大量的請求,從而
45、導致 OOM。2)CachedThPool 和 ScheduledThPool:的創建線程數量為 Integer.MAX_VALUE,可能會創建大量的線程,從而導致 OOM。5. 【強制】SimpleDateFormat 是線程不安全的類,不要定義為 static 變量,如果定義為static,必須加鎖,或者使用 DateUtils 工具類。正例:注意線程安全,使用 DateUtils。亦推薦如下處理:private static final ThOverrideLocal<DateFormat> df = new ThLocal<DateFormat>() prote
46、cted DateFormat initialValue() return new SimpleDateFormat("yyyy-MM-dd");說明:如果是 JDK8 的應用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar,DateTimeFormatter 代替Simpledateformatter,官方給出的解釋:simple beautiful strong-safe。immutable th6. 【強制】高并發時,同步調用應該去考量鎖的性能損耗。能用無鎖數據結構,就不要用鎖;能鎖區塊,就不要鎖整個體;能用對象鎖,就不要
47、用類鎖。7. 【強制】對多個資源、數據庫表、對象同時加鎖時,需要保持一致的加鎖順序,否則可能會造成死鎖。說明:線程一需要對表 A、B、C 依次全部加鎖后才可以進行更新操作,那么線程二的加鎖順序也必須是 A、B、C,否則可能出現死鎖。8. 【強制】并發修改同一時,避免更新丟失,需要加鎖。要么在應用層加鎖,要么在緩存加鎖,要么在數據庫層使用樂觀鎖,使用 version 作為更新依據。概率小于 20%,推薦使用樂觀鎖,否則使用悲觀鎖。樂觀鎖的重試次說明:如果每次數不得小于 3 次。9. 【強制】多線程并行處理定時任務時,Timer 運行多個 TimeTask 時,只要其中之一沒有捕獲拋出的異常,其它
48、任務便會自動終止運行,使用 ScheduledExecutorService 則沒有這個問題。14 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊10. 【推薦】使用 CountDownLatch 進行異步轉同步操作,每個線程前必須調用 countDown,線程執行代碼注意 catch 異常,確保 countDown可以執行,避免主線程無法執行至 await,直到超時才返回結果。說明:注意,子線程拋出異常堆棧,不能在主線程 try-catch 到。11. 【推薦】避免 Random 實例被多線程使用,雖然共享該實例是線程安全的,但會因競爭同一seed 導致的性能下降。java.uti
49、l.Random的實例或者 Math.random()實例。LocalRandom,在 JDK7 之前,可以做到每個說明:Random 實例正例:在 JDK7 之后,可以直接使用 API Th線程一個實例。12. 【推薦】在并發場景下,通過雙重檢查鎖(double-checked locking)實現延遲初始化的優化問題隱患(可參考 The "Double-Checked Locking is Broken" Declaration),推薦問題解決方案中較為簡單一種(適用于 JDK5 及以上版本),將目標屬性反例:class Foo private Helper helpe
50、r = null; public Helper getHelper() if (helper = null) synchronized(this) if (helper = null)helper = new Helper();return helper;/ other functions and members.13. 【參考】volatile 解決多線程內存不可見問題。對于一寫多讀,是可以解決變量同步問題, 但是如果多寫,同樣無法解決線程安全問題。如果是 count+操作,使用如下類實現: AtomicInteger count = new AtomicInteger(); count.a
51、ddAndGet(1); 如果是 JDK8,推薦使用 LongAdder 對象,比 AtomicLong 性能更好(減少樂觀鎖的重試次數)。14. 【參考】 HashMap 在容量不夠進行 resize 時由于高并發可能出現死鏈,導致 CPU 飆升,在開發過程中注意規避此風險。為 volatile 型。15. 【參考】ThLocal 無法解決共享對象的更新問題,ThLocal 對象建議使用 static修飾。這個變量是一個線程內所有操作共有的,所以設置為靜態變量,所有此類實例共享此靜態變量 ,也就是說在類第一次被使用時裝載,只分配一塊空間,所有此類的對象(只要是這個線程內定義的)都可以操控這個
52、變量。15 / 37用于商業用途,違者 阿里巴巴 Java 開發手冊(七)語句1. 【強制】在一個 switch 塊內,每個 case 要么通過 break/return 等來終止,要么注釋說明程序將繼續執行到哪一個 case 為止;在一個 switch 塊內,都必須包含一個 default 語句并且放在最后,即使它什么代碼也沒有。2. 【強制】在 if/else/for/while/do 語句中必須使用大括號,即使只有一行代碼,避免使用下面的形式:if (condition) statements;3. 【推薦】推薦盡量少用 else, if-else 的方式可以改寫成:if (condit
53、ion) .return obj;/ 接著寫 else 的業務邏輯代碼;說明:如果非得使用 if().else if().else.方式表達邏輯,【強制】超過 3 層, 超過請使用狀態設計模式。正例:邏輯上超過 3 層的 if-else 代碼可以使用衛語句,或者狀態模式來實現。4. 【推薦】除常用(如 get/is)等外,不要在條件中執行其它復雜的語句,將復雜邏輯的結果賦值給一個有意義的變量名,以提高可讀性。說明:很多 if 語句內的邏輯相當復雜,閱讀者需要分析條件表樣的條件執行什么樣的語句,那么,如果閱讀者分析邏輯表正例:的最終結果,才能明確什么錯誤呢?/偽代碼如下boolean existed = (file.open(fileName, "w") != null) && (.) | (.); if (existed) .反例:if (file.open(fileName, "w") != null) && (.) | (.) .5. 【推薦】循環體中的語句要考量性能,以下操作盡量移至循環體,如定義對象、變量、獲取數據庫連接,進行不必要的 try-catch 操作(這個 try-catch 是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 影像科病理管理制度
- 心外科流程管理制度
- 快檢室設備管理制度
- 總公司貨運管理制度
- 總經理預約管理制度
- 慈善會培訓管理制度
- 戰略部部門管理制度
- 排放瓦斯油管理制度
- 接種證查驗管理制度
- 收支結余率管理制度
- 戰略性績效管理體系設計實踐課件
- 電腦的認識 完整版課件
- GB∕T 37201-2018 鎳鈷錳酸鋰電化學性能測試 首次放電比容量及首次充放電效率測試方法
- DB62∕T 2997-2019 公路工程工地建設標準
- 2021年河南中考復習專項:中考材料作文(解析版)
- 運動控制系統課程設計-雙閉環直流調速系統
- 提高學生課堂參與度研究的課題
- 中央司法警官學院招生政治考察表
- 原產地規則培訓講座課件
- GB_T 22627-2022水處理劑 聚氯化鋁_(高清-最新版)
- 藥品不良反應報告表范例
評論
0/150
提交評論