zoukankan      html  css  js  c++  java
  • 并发队列对比之一:ConcurrentLinkedQueue、LinkedBlockingQueue对比分析

    关于ConcurrentLinkedQueue和LinkedBlockingQueue:

        1.LinkedBlockingQueue是使用锁机制,ConcurrentLinkedQueue是使用CAS算法,虽然LinkedBlockingQueue的底层获取锁也是使用的CAS算法

        2.关于取元素,ConcurrentLinkedQueue不支持阻塞去取元素,LinkedBlockingQueue支持阻塞的take()方法,如若大家需要ConcurrentLinkedQueue的消费者产生阻塞效果,需要自行实现

        3.关于插入元素的性能,从字面上和代码简单的分析来看ConcurrentLinkedQueue肯定是最快的,但是这个也要看具体的测试场景,我做了两个简单的demo做测试,测试的结果如下,两个的性能差不多,但在实际的使用过程中,尤其在多cpu的服务器上,有锁和无锁的差距便体现出来了,ConcurrentLinkedQueue会比LinkedBlockingQueue快很多:

    package com.dxz.queue.linked;
    
    import java.util.concurrent.ConcurrentLinkedQueue;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.LinkedBlockingQueue;
    
    public class ProducerConcurrnetLinkedQueue implements Runnable{  
          
        //容器  
        private final ConcurrentLinkedQueue<Bread> queue;
        private final CountDownLatch cdl;
          
        public ProducerConcurrnetLinkedQueue(ConcurrentLinkedQueue<Bread> queue, CountDownLatch cdl){  
            this.queue = queue;  
            this.cdl = cdl;
        }  
      
        @Override  
        public void run() {  
            for(int i=0;i<100000; i++){  
                produce(i);  
            }
            cdl.countDown();
        }  
          
        public void produce(int i){  
            /** 
             * put()方法是如果容器满了的话就会把当前线程挂起 
             * offer()方法是容器如果满的话就会返回false。 
             */  
            try {  
                Bread bread = new Bread();
                bread.setName(""+i);
                queue.offer(bread);
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
    
    package com.dxz.queue.linked;
    
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ConcurrentLinkedQueue;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.LinkedBlockingQueue;
    
    public class ClientPut {  
      
        public static void main(String[] args) throws InterruptedException {  
            int capacity = 9000000;
            //testArray(capacity);    //put in ArrayBlockingQueue size:=1000000,use time:=624
            //testLinked(capacity);    //put in LinkedBlockingQueue size:=1000000,use time:=289
            testConcurrentLinked(); //put in ConcurrentLinkedQueue size:=1000000,use time:=287
            
        }
        
        private static void testArray(int capacity) throws InterruptedException {
            ArrayBlockingQueue<Bread> queue = new ArrayBlockingQueue<Bread>(capacity);  
            CountDownLatch cdl = new CountDownLatch(10);
            ExecutorService es = Executors.newFixedThreadPool(10);
            long start = System.currentTimeMillis();
            for(int i = 0; i < 10;i++) {
                es.submit(new ProducerArray(queue, cdl));
            }
            cdl.await();
            long end = System.currentTimeMillis();
            es.shutdown();
            System.out.println("put in ArrayBlockingQueue size:="+queue.size() +",use time:="+(end-start));
        }
    
        private static void testLinked(int capacity) throws InterruptedException {
            LinkedBlockingQueue<Bread> queue = new LinkedBlockingQueue<Bread>(capacity);
            CountDownLatch cdl = new CountDownLatch(10);
            ExecutorService es = Executors.newFixedThreadPool(10);
            long start = System.currentTimeMillis();
            for(int i = 0; i < 10;i++) {
                es.submit(new ProducerLinked(queue, cdl));
            }
            cdl.await();
            long end = System.currentTimeMillis();
            es.shutdown();
            System.out.println("put in LinkedBlockingQueue size:="+queue.size() +",use time:="+(end-start));
        }
        
        private static void testConcurrentLinked() throws InterruptedException {
            ConcurrentLinkedQueue<Bread> queue = new ConcurrentLinkedQueue<Bread>();
            CountDownLatch cdl = new CountDownLatch(10);
            ExecutorService es = Executors.newFixedThreadPool(10);
            long start = System.currentTimeMillis();
            for(int i = 0; i < 10;i++) {
                es.submit(new ProducerConcurrnetLinkedQueue(queue, cdl));
            }
            cdl.await();
            long end = System.currentTimeMillis();
            es.shutdown();
            System.out.println("put in ConcurrentLinkedQueue size:="+queue.size() +",use time:="+(end-start));
        }
      
    }
  • 相关阅读:
    单片机与嵌入式系统中C语言的位运算小记
    #ifndef、#def、#endif说明
    Freertos学习初识任务函数
    IAR(EWARM)下移植FreeRTOS到STM32F10x笔记
    visio 画 弯曲 箭头 ( 波浪线 曲线)
    dos 中tree的使用方法
    Win7下Borland C++ 4.5 & TASM5.0调试uC/OSII
    (*(volatile unsigned long *)
    有关推挽输出、开漏输出、复用开漏输出、复用推挽输出以及上拉输入、下拉输入、浮空输入、模拟输入区别
    POJ 1236 Network of Schools
  • 原文地址:https://www.cnblogs.com/duanxz/p/2721290.html
Copyright © 2011-2022 走看看