Queue队列家族介绍
微信公众号文章列表:关注公众号(coding_song)阅读更清晰,附件为微信二维码
Queue
队列接口,是一个为在处理前保存元素而设计的集合
Queue接口方法
add(E e)
:向集合中添加一个元素,如果是容量受限的队列(有界队列),当队列已满后,继续向队列中添加元素,将会抛异常,添加成功后,返回trueoffer(E e)
:向集合中添加一个元素,如果是容量受限的队列(有界队列),当队列已满后,继续向队列中添加元素,将会返回false,否则返回true
remove()
:获取并删除队列中的头元素,当队列为空时,调用此方法,将会抛出异常,删除成功后,返回被删除的元素对象poll()
:获取并删除队列中的头元素,当队列为空时,返回null,否则返回被删除的元素对象element()
:获取队列中的头元素,当队列为空时,将抛出异常,否则返回队列的头元素peek()
:获取队列中的头元素,当队列为空时,返回null,否则返回队列的头元素
BlockingQueue
阻塞队列接口,继承Queue接口,阻塞队列中的方法有4中形式,1)直接抛出一个异常;2)返回一个特定的值null或false等;3)无限期阻塞当前线程直到满足条件才继续后续操作;4)在给定的最大时间限制内阻塞;阻塞队列中的所有实现都是线程安全的,如果队列中没有元素,当获取队列中的元素时,将会一直阻塞,直到队列中有值后,才会返回元素内容;当向队列中添加元素时,如果队列已满,将会一直阻塞,直到队列中有空间时,才会将元素添加到队列中;
BlockingQueue接口方法
put(E e)
:向队列中添加元素,当队列已满时,将会一直阻塞,直到队列有空间时,才会成功将数据添加到队列中offer(E e,long timeout,TimeUnit unit)
:将指定的元素插入到队列中,如有必要,等待指定的等待时间以使空间可用,在timeout时间后,如果队列中还是没有空间可用,将会抛出异常take()
:获取并移除头元素,当队列中没有元素时,将会一直阻塞,直到有元素时,将会移除队列的头元素poll(long timeout,TimeUnit unit)
:检索并删除此队列的头元素,如果需要,可等待指定的等待时间以使元素可用drainTo(Collection<?superE> c)
:移除队列中的所有元素,并将这些元素添加到给定的集合中
Queue实现类
*队列
:PriorityBlockingQueue、ConcurrentLinkedQueue有界队列
:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue阻塞队列
:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue
阻塞队列实现类PriorityBlockingQueue、ArrayBlockingQueue、LinkedBlockingQueue等都是线程安全的,内部调用ReentrantLock的lock或lockInterruptibly方法进行加锁,等待逻辑执行完成后,使用调用unlock释放锁
PriorityBlockingQueue
:是一个使用与类PriorityQueue相同的排序规则并提供阻塞检索操作的无边界阻塞优先级队列,优先级队列不允许使用null元素,依赖自然排序的优先级队列不允许插入不能比较的对象ConcurrentLinkedQueue
:是一个基于链表节点的、线程安全的*队列,遵循先进先出规则,队列中的头元素是队列中时间最长的元素,尾元素是队列中时间最短的元素;添加元素时,从队列尾添加元素,读取元素时,从队列的头读取元素;当多个线程需要共享一个集合时,可以使用ConcurrentLinkedQueue来保存集合,此集合不允许使用null元素ArrayBlockingQueue
:是一个由数组组成的有界阻塞队列,此队列遵循先进先出的原则,队列中的头元素是队列中时间最长的元素,尾元素是队列中时间最短的元素;添加元素时,从队列尾添加元素,读取元素时,从队列的头读取元素;这是一个景点的有界缓冲队列,是一个有生产者添加数据、消费者读取数据的固定大小的数组;一旦创建好ArrayBlockingQueue,其容量大小不可改变LinkedBlockingQueue
:是一个基于链接节点的、大小可选的有界阻塞队列,此队列遵循先进先出原则,队列中的头元素是队列中时间最长的元素,尾元素是队列中时间最短的元素;添加元素时,从队列尾添加元素,读取元素时,从队列的头读取元素;此队列比ArrayBlockingQueue具有更高的吞吐量,但其性能不好预测SynchronousQueue
:阻塞队列,其中每个put/offer操作必须等待另一个线程执行相应的take/poll操作,反之亦然;其内部没有数据缓存空间,不用来保存数据;数据是在配对的生产者和消费者线程之间直接传递的,并不会将数据缓冲数据到队列中,使用示例如下
-
publicstaticvoid main(String[] args)throwsInterruptedException{
-
SynchronousQueue queue =newSynchronousQueue();
-
Runnable offer =()->{
-
try{
-
queue.offer(1,1000,TimeUnit.MILLISECONDS);
-
}catch(InterruptedException e){
-
e.printStackTrace();
-
}
-
};
-
Runnable poll =()->System.out.println("test SynchronousQueue:" + queue.poll());
-
newThread(offer).start();
-
Thread.sleep(1000);
-
newThread(poll).start();
-
}
创建offer生产者线程和poll消费者线程,然后启动两个线程,最终生产者线程将数据传递给消费者线程,打印结果为:testSynchronousQueue:1
推荐阅读:回首过往、展望未来
扫码关注获取更多文章
上一篇: python_random模块_2021.6.10
下一篇: springboot2实战三-配置类