1. 程式人生 > >多執行緒下TreeMap訪問造成CPU過載

多執行緒下TreeMap訪問造成CPU過載

最近發現webapp專案在客戶的server執行幾個小時後,會出現整個Server執行很慢,CPU高達100%,剛開始一直認為是哪裡記憶體洩露,但一看該應用佔用的記憶體並沒有一直增長,也保持在一個合理的狀態。
在排查故障的過程中,發現程式碼中使用public static TreeMap<String, String> treemap = new TreeMap<String, String>();來記錄狀態資訊,並且發現multi thread put/get訪問該物件,就聯想到HashMap是非執行緒安全,是否TreeMap也是呢?上某度一查,結果還真是。
那如何修改呢?Oracle官網http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6423457建議使用ConcurrentHashMap來替換,執行緒安全,並且查詢效率比TreeMap高。但由於專案中需要對該Map按自然順序或自定義順序遍歷鍵,剛好需要用到TreeMap的特性–排序,因此可以在方法上加syncronized 或者定義如下TreeMap

public static Map<String,String> treemap = Collections.synchronizedMap(new TreeMap<String,String>());

修改後再在客戶server上執行,該問題就解決了。
但誠如@qq_31279701所說,這樣的效能實在太差了,可以使用ConcurrentSkipListMap。這是一個支援高併發度的有序雜湊表,並且是無鎖的,可在多執行緒環境下替代TreeMap。JDK1.6開始就已經支援ConcurrentSkipListMap。
感謝@qq_31279701的提醒與指正!