java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > ConcurrentLinkedQueue使用

Java中的ConcurrentLinkedQueue使用解析

作者:小宇宙121

这篇文章主要介绍了Java中的ConcurrentLinkedQueue使用解析,一个基于链接节点的无界线程安全队列,此队列按照 FIFO(先进先出)原则对元素进行排序,队列的头部是队列中时间最长的元素,需要的朋友可以参考下

定义

一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。

队列的头部是队列中时间最长的元素。

队列的尾部是队列中时间最短的元素。 新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。

当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。

此队列不允许使用 null 元素。

函数

注意:当需要判断队列是否有值时,推荐使用isEmpty(),size()的时间复杂度是o(n),当数据量很大时,会比isEmpty()消耗明显多的时间。

下面比较一下isEmpty()和size()耗时:

public class ConcurrentLinkedQueueTest {
    private static final Logger logger = LoggerFactory.getLogger(ConcurrentLinkedQueueTest.class);
    public static void main(String args[]) throws InterruptedException {
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
        int serviceNum = 10;//服务窗口数
        int perpeoNum = 10000;//买车票人数
        CountDownLatch countDownLatch = new CountDownLatch(serviceNum);//初始值是线程的个数
        //将买票人数放入队列
        for(int i=0; i<perpeoNum; i++){
            queue.add("买票人_" + i);
        }
        //执行10个线程从队列取出买票人
        logger.info("-----开始卖票了--------");
        long start = System.currentTimeMillis();
        ExecutorService service = Executors.newFixedThreadPool(10);
        for(int i=0; i<serviceNum; i++){
            service.submit(new Windows("窗口号_" + i , queue, countDownLatch));
        }
        //等待所有线程都执行完,主线程再执行。
        countDownLatch.await();
		logger.info("-----所有人都买完票了----");
        long time = System.currentTimeMillis() - start;
        logger.info("总消耗时间是:{}",time);
        service.shutdown();
    }
    private static class Windows implements Runnable{
        private String name;
        private ConcurrentLinkedQueue queue;
        private CountDownLatch countDownLatch;
        public Windows(String name, ConcurrentLinkedQueue queue, CountDownLatch countDownLatch){
            this.name = name;
            this.queue = queue;
            this.countDownLatch = countDownLatch;
        }
        @Override
        public void run() {
        //   while (!queue.isEmpty()){
            while(queue.size() > 0){  
                logger.info(queue.poll()  + "---买票完毕---{}", name );
            }
            countDownLatch.countDown();//线程执行完,count值-1
        }
    }
}

执行结果: 使用size(),耗时511ms; 使用isEmpty(),耗时125ms; 所以优先使用isEmpty();

CountDownLatch

CountDownLatch是一个非常实用的多线程控制工具类,例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。

每当一个线程完成了自己的任务后,计数器的值就会减1。

当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。

到此这篇关于Java中的ConcurrentLinkedQueue使用解析的文章就介绍到这了,更多相关ConcurrentLinkedQueue使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文