码迷,mamicode.com
首页 > 其他好文 > 详细

使用ConcurrentLinkedQueue惨痛的教训【转】

时间:2017-03-14 00:16:32      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:util   测试   cut   代码   ring   []   detail   消息   size   

转自: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().

总结了下, 在缺乏性能测试的情况下,对自己的编程要求更加要严格,特别是在生产环境下更是要小心谨慎。

使用ConcurrentLinkedQueue惨痛的教训【转】

标签:util   测试   cut   代码   ring   []   detail   消息   size   

原文地址:http://www.cnblogs.com/gotodsp/p/6545560.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!