java队列之LinkedBlockingQueue和ConcurrentLinkedQueue

java队列之LinkedBlockingQueue和ConcurrentLinkedQueue前言 LinkedBlocki 和 ConcurrentLi 是 Java 高并发场景中最常使用的队列 高并发场景中经常用的数据结构 但它们之间仍有细微的特征和行为差异 下面说一下两者及区别

欢迎大家来到IT世界,在知识的湖畔探索吧!

前言:

LinkedBlockingQueueConcurrentLinkedQueue 是 Java 高并发场景中最常使用的队列。高并发场景中经常用的数据结构,但它们之间仍有细微的特征和行为差异。下面说一下两者及区别。

LinkedBlockingQueue

首先 LinkedBlockingQueue 是一个 “可选且有界” 的阻塞队列实现,你可以根据需要指定队列的大小。 接下来,我将创建一个LinkedBlockingQueue,它最多可以包含100个元素:

BlockingQueue 
  
    boundedQueue = new LinkedBlockingQueue<>(100); 
  

欢迎大家来到IT世界,在知识的湖畔探索吧!

也可以通过不指定大小,来创建一个无界的 LinkedBlockingQueue:

欢迎大家来到IT世界,在知识的湖畔探索吧!BlockingQueue 
   
     unboundedQueue = new LinkedBlockingQueue<>(); 
   

无界队列表示在创建时未指定队列的大小。因此,队列可以随着元素的添加而动态增长。但是,如果没有剩余内存,则队列将抛出 java.lang.OutOfMemory 错误。

可以从现有的集合来创建 LinkedBlockingQueue:

java队列之LinkedBlockingQueue和ConcurrentLinkedQueue

欢迎大家来到IT世界,在知识的湖畔探索吧!

LinkedBlockingQueue 实现了BlockingQueue接口,该接口为它提供了阻塞性质

阻塞队列表示如果访问线程已满(当队列有界时)或变为空,则队列将阻塞该线程。如果队列已满,则添加新元素将阻塞访问线程,除非新元素有可用空间。类似地,如果队列为空,则访问元素会阻塞调用线程:

ExecutorService executorService = Executors.newFixedThreadPool(1); LinkedBlockingQueue 
   
     queue = new LinkedBlockingQueue<>(); executorService.submit(() -> {   try {     queue.take();   }   catch (InterruptedException e) {     // exception handling   } }); 
   

在上面的代码片段中,我们正在访问一个空队列。因此,take() 方法阻塞调用线程。
LinkedBlockingQueue 的阻塞特性与一些开销相关。这个代价是因为每个put或take操作在生产者线程或使用者线程之间都是锁争用的。因此,在许多生产者和消费者的情况下,put和take 动作可能会慢一些。

ConcurrentLinkedQueue

ConcurrentLinkedQueue 是一个无边界、线程安全且无阻塞的队列。

创建一个空的 ConcurrentLinkedQueue:

欢迎大家来到IT世界,在知识的湖畔探索吧!ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

同上面一样,我们也可以从现有集合创建 ConcurrentLinkedQueue:

java队列之LinkedBlockingQueue和ConcurrentLinkedQueue

不同于 LinkedBlockingQueue, ConcurrentLinkedQueue是非阻塞的队列。因此,即使队列为空(empty),它也不会阻塞线程。相反,它会返回 空(null) 。虽然它是无界的,但如果没有额外的内存来添加新元素,它依旧会抛出 java.lang.OutOfMemory 错误。 除了非阻塞之外,ConcurrentLinkedQueue还有其他特性。 在任何生产者-消费者场景中,消费者都不会满足于生产者;但是,多个生产者将相互竞争:

int element = 1; ExecutorService executorService = Executors.newFixedThreadPool(2); ConcurrentLinkedQueue 
   
     queue = new ConcurrentLinkedQueue<>();   Runnable offerTask = () -> queue.offer(element);   Callable 
    
      pollTask = () -> {   while (queue.peek() != null) {     return queue.poll().intValue();   }   return null; };   executorService.submit(offerTask); Future 
     
       returnedElement = executorService.submit(pollTask); assertThat(returnedElement.get().intValue(), is(equalTo(element))); 
      
     
   

第一个任务 offerTask 向队列中添加元素,第二个任务 pollTask 从队列中检索元素。pollTask 首先检查队列中的元素,因为ConcurrentLinkedQueue是非阻塞的,并且可以返回null值。

两者异同

LinkedBlockingQueue 和 ConcurrentLinkedQueue 都是队列实现,并具有一些共同特征。让我们讨论一下这两个队列的相似之处:

  1. 实现 Queue 接口
  2. 它们都使用 linked nodes 存储节点
  3. 都适用于并发访问场景

区别:

java队列之LinkedBlockingQueue和ConcurrentLinkedQueue

总结

上述进行了queue队列之LinkedBlockingQueueConcurrentLinkedQueue的讲述及明确两则之间的区别,在项目中可以根据需要运用两者。


免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/89606.html

(0)
上一篇 1小时前
下一篇 1小时前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信