0
点赞
收藏
分享

微信扫一扫

LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue、ConcurrentLinkedQueue、TransferQueue的原理与使用场景


在jdk中有许多的队列,队列的使用还是有一些难度的,因为涉及到了并发等概念,现在我们列举一下队列的特点:

  • 并发情况下不会有线程安全问题
  • 队列都有元素
  • 都有添加(生产者端使用)、获取(消费者端使用)功能
  • 基本上的使用场景都是在多线程、高并发的场景
    在jdk中的队列有如下几种:

1、LinkedBlockingQueue

LinkedBlockingQueue是使用比较多的队列,在SingleThreadPool(单个线程的线程池)、FixedThreadPool(固定线程数的线程池)使用的都是LinkedBlockingQueue。
1、在LinkedBlockingQueue中有两个ReentrantLock,takeLock和putLock分别是在添加元素和取出元素的时候添加的锁。
2、LinkedBlockingQueue是无界队列。

2、ArrayBlockingQueue

ArrayBlockingQueue是有界队列,在阿里的开源框架RocketMq中就使用到了,其添加和获取都是用的同一个ReentrantLock。

3、SynchronousQueue

SynchronousQueue是只有一个元素的队列,

  • 其添加和获取方法都用到了transfer方法

public boolean offer(E e) {
if (e == null) throw new NullPointerException();
return transferer.transfer(e, true, 0) != null;
}

public E take() throws InterruptedException {
E e = transferer.transfer(null, false, 0);
if (e != null)
return e;
Thread.interrupted();
throw new InterruptedException();
}

其是根据是否有元素来区分是添加元素还是获取元素。

  • 其有两种元素添加获取方式,非公平获取和公平获取
    非公平用的是TransferStack,是后进先出的方式
    公平方式用的是TransferQueue,是先进先出方式
  • 加锁是用的CAS的方式替换
    使用场景:在CachedThreadPool线程池中,使用到了SynchronousQueue。

4、ConcurrentLinkedQueue

ConcurrentLinkedQueue数据结构进行了非常巧妙的设计,在添加是从tail节点,获取是从head节点,而且做到了方并发,因为不用锁,所以效率更高。
在netty的读取byteBuffer和获取Selector中都用了ConcurrentLinkedQueue。具体详细原理,可以网上搜索,在此不再赘述

5、LinkedTransferQueue

LinkedTransferQueue是jdk才出现的队列,是LinkedBlockingQueue、SynchronousQueue、ConcurrentLinkedQueue的超集,实现了他们三个的功能,其添加和获取都是用的xfer方法。


举报

相关推荐

0 条评论