最近發(fā)現(xiàn)webapp項目在客戶的server運(yùn)行幾個小時后检激,會出現(xiàn)整個Server運(yùn)行很慢,CPU高達(dá)100%纤子,剛開始一直認(rèn)為是哪里內(nèi)存泄露胞此,但一看該應(yīng)用占用的內(nèi)存并沒有一直增長,也保持在一個合理的狀態(tài)涩金。
在排查故障的過程中谱醇,發(fā)現(xiàn)代碼中使用public static TreeMap<String, String> treemap = new TreeMap<String, String>();
來記錄狀態(tài)信息,并且發(fā)現(xiàn)multi thread put/get訪問該對象步做,就聯(lián)想到HashMap是非線程安全副渴,是否TreeMap也是呢全度?上某度一查煮剧,結(jié)果還真是。
那如何修改呢?Oracle官網(wǎng)http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6423457建議使用ConcurrentHashMap來替換勉盅,線程安全佑颇,并且查詢效率比TreeMap高。但由于項目中需要對該Map按自然順序或自定義順序遍歷鍵草娜,剛好需要用到TreeMap的特性--排序挑胸,因此可以在方法加syncronized 或者定義如下
public static Map<String,String> treemap = Collections.synchronizedMap(new TreeMap<String,String>());
修改后再在客戶server上運(yùn)行,該問題就解決了宰闰。
但這樣的做性能實在太差了茬贵,可以使用ConcurrentSkipListMap。這是一個支持高并發(fā)度的有序哈希表议蟆,并且是無鎖的闷沥,可在多線程環(huán)境下替代TreeMap。JDK1.6開始就已經(jīng)支持ConcurrentSkipListMap咐容。