使用ConcurrentLinkedQueue慘痛的教訓【轉】


轉自:http://blog.csdn.net/jackpk/article/details/49634577

服務端原本有個定時任務對一個集合ArrayList 中的消息做處理。 因為考慮到處理消息是先進先出原則,所以優化的時候考慮改用ConcurrentLinkedQueue 當時沒仔細深入研究過這個集合就匆匆上線了。結果剛上線第二天就出問題了。服務端一次優化演變成了一個缺陷,還好及時回退了版本,后果才不是很嚴重。回退后對ConcurrentLinkedQueue 做了一個簡單的測試代碼,如下:

 1 import java.util.concurrent.ConcurrentLinkedQueue;
 2 import java.util.concurrent.CountDownLatch;
 3 import java.util.concurrent.ExecutorService;
 4 import java.util.concurrent.Executors;
 5 
 6 public class ConcurrentLinkedQueueTest {
 7     
 8     private static ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
 9     
10     private static int count = 100000;
11     
12     private static int count2 = 2; // 線程個數
13     
14     private static CountDownLatch cd = new CountDownLatch(count2);
15     
16     public static void dothis() {
17         for (int i = 0; i < count; i++) {
18             queue.offer(i);
19         }
20     }
21     
22     public static void main(String[] args) throws InterruptedException {
23         long timeStart = System.currentTimeMillis();
24         ExecutorService es = Executors.newFixedThreadPool(4);
25         ConcurrentLinkedQueueTest.dothis();
26         for (int i = 0; i < count2; i++) {
27             es.submit(new Poll());
28         }
29         cd.await();
30         System.out.println("cost time " + (System.currentTimeMillis() - timeStart) + "ms");
31         es.shutdown();
32     }
33     
34     static class Poll implements Runnable {
35         @Override
36         public void run() {
37             //while (queue.size() > 0) {    // 效率低,每次都需要計算整個隊列的個數
38             while (!queue.isEmpty()) {
39                 System.out.println(queue.poll());
40             }
41             cd.countDown();
42         }
43     }
44 }

運行結果:

  costtime 2360ms

改用while (queue.size() > 0)后運行結果:

  cost time 46422ms

結果居然相差那么大,看了下ConcurrentLinkedQueue的API 原來.size() 是要遍歷一遍集合的,難怪那么慢,所以盡量要避免用size而改用isEmpty().

總結了下, 在缺乏性能測試的情況下,對自己的編程要求更加要嚴格,特別是在生產環境下更是要小心謹慎。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM