生產環境遇到的hashMap非安全執行緒問題java.lang.thread.waiting

來源:互聯網
上載者:User

標籤:tab   廣告   thread   resource   ati   logs   .com   過程   www.   

寫在前面:工作有幾年了,從入門到現在,遇到也解決了一些問題。(當然,架構層級的暫時還沒有)一直以來,都是從部落格園以及其他各大社區搜羅出來的各種fix方法。目前稍有閑暇時間,在看過大V沈劍的博文後,我也鼓起勇氣來書寫部落格,記錄工作中遇到和解決的問題(其中當然也包括我在博園擷取的各種解決方案;能找到原博文的小弟一定會註明出處。)因為總覺得自己水平不夠,怕寫出來的文章誤導了別人。以下是這周生產環境遇到的一個問題,寫出來供大家參考。現象

  周五一大早,車子都沒停穩(電動車),群裡就開始在詢問誰最近的代碼有比較耗時耗效能的操作,大家都說沒有。然後就是一張:

cpu已經飆到1600+,這個問題還是比較嚴重的。隨後聯絡到營運組給出tomcat作業記錄排查是否有錯誤。經過排查日誌發下如下錯誤:

看到後飛速坐到位置上,去查詢對應的錯誤碼;

 分析和搜尋:

  以下是部分代碼:

 1     public static Map<String,String> cityCodeMap = new HashMap<String, String>(); 2      3     public static Map<String,String> provinceMap = new HashMap<String, String>(); 4      5     public static List<String> sensitiveWordList = new ArrayList<String>(); 6      7     public static String getCityCodeByNumber(String phoneNumber) 8     { 9         String start = StringUtils.substring(phoneNumber, 0, 7);10         if(StringUtils.isEmpty(start))11         {12             return "000";13         }14         Map<String, String> cityCodes = getCityCodes();15         String cityCode = cityCodes.get(start);16         if(StringUtils.isEmpty(cityCode))17         {18             return "000";19         }20         return cityCode;21     }

 

主要用於擷取手機號碼的號段對應的城市編碼,項目的某個模組(不能打廣告吧)需要用到。並且每次調用都用用到;咋一看,感覺沒啥問題,項目中好多地方都是這麼乾的。接著又在測試環境和本地環境跑一邊代碼,都運行正常。

然後就搜尋了java.lang.thread.waiting 這個異常,在這篇博文中搜到相關問題,http://www.cnblogs.com/zhengyun_ustc/archive/2013/03/18/tda.html

才發現可能是多線程引發的問題。

這裡列舉兩個比較解釋特別詳細的博文,源碼跟蹤和分析過程都非常詳細。

http://coding-geek.com/how-does-a-hashmap-work-in-java/

https://coolshell.cn/articles/9606.html

  

  此種情況雖然是機率發生的,但是在並發量比較大的情況下,還是及其危險的。如果發現不及時,很有可能導致單點故障甚至整個叢集不可用。又根據自己項目代碼的情況分析,主要是因為在初始化中,迴圈向map中put新元素導致map擴容rehash時產生了死迴圈。

初始化代碼:

    public static Map<String,String> getCityCodes() {        if(cityCodeMap.isEmpty())        {            Set<String> keySet = ResourceBundle.getBundle("config/citynum").keySet();            for (String key : keySet) {                String cityCode = PropertiesUtil.getKey("config/citynum",key);                cityCodeMap.put(key, cityCode);            }        }        return cityCodeMap;    }

ps:此處的citynum中有幾萬個索引值對。

解決辦法:
  1. Hashtable
  2. ConcurrentHashMap
  3. Synchronized Map

可自行搜尋實現原理,很多大神、大仙兒都闡述的比我詳細。

都說程式員都是懶人,我不認同。我們只不過是想用最少的代碼去解決問題。所以,我們的改良方案就是把HashMap直接換成ConcurrentHashMap。

 

生產環境遇到的hashMap非安全執行緒問題java.lang.thread.waiting

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.