简介
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接 口。Deque接口继承了Queue接口,因此我们可以把LinkedList当成Queue来用。
应用场景
一般情况下,如果是一些及时消息的处理,并且处理时间很短的情况下是不需要使用队列的,直接阻塞式的方法调用就可以了。但是,如果在消息处理的时候特别费时间,这个时候如果有新的消息来了,就只能处于阻塞状态,造成用户等待。这个时候在项目中引入队列是十分有必要的。当我们接受到消息后,先把消息放到队列中,然后再用新的线程进行处理,这个时候就不会有消息的阻塞了。下面就跟大家介绍两种队列的使用,一种是基于内存的,一种是基于数据库的。
————————————————
版权声明:本文为CSDN博主「在远行的路上」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lzy_lizhiyang/article/details/48311925
接口与接口方法
public interface Queue<E> extends Collection<E> {
/**
* 如果可能,将指定的元素插入到此队列中
* 在不违反容量限制的情况下,立即返回
* 如果无法在此处添加元素,则抛出 IllegalStateException
* 如果指定元素的类阻止它被添加到此队列中,则抛出 ClassCastException
* 如果指定的元素为空且此队列不允许空元素,则抛出 NullPointerException
* 如果该元素的某些属性阻止它被添加到此队列中,则抛出 IllegalArgumentException
*/
boolean add(E e);
/**
* 如果可以在不违反容量限制的情况下立即将指定的元素插入到此队列中。
*
* 当使用受容量限制的队列时,这种方法通常优于add ,后者只能通过抛出异常来插入元素。
*
* @param e 要添加的元素
* @return 添加元素如果队列已满直接返回false,队列未满则直接插入并返回true
* @throws 如果指定元素的类阻止它被添加到此队列中,则抛出 ClassCastException
* 如果指定的元素为空且此队列不允许空元素,则抛出 NullPointerException
* 如果该元素的某些属性阻止它被添加到此队列中,则抛出 IllegalArgumentException
*/
boolean offer(E e);
/**
* 检索并移除此队列的头部。 此方法与poll ()的不同之处在于,如果队列为空,它将引发异常。
*
* 返回此队列的头部
* 如果队列为空,则抛出 NoSuchElementException
*/
E remove();
/**
* 检索并移除此队列的头部,如果此队列为空,则返回null。
*/
E poll();
/**
* 检索但不移除此队列的头部。 此方法与peek的不同之处在于,如果队列为空,它将引发异常。
* 返回此队列的头部
* 如果队列为空,则抛出 NoSuchElementException
*/
E element();
/**
* 检索但不移除此队列的头部。 此方法与peek的不同之处在于,如果队列为空,它将返回null。
*
* 返回此队列的头部,如果该队列为空,则返回{@code null }
*/
E peek();
}
常用队列
阻塞队列和普通队列(BlockingQueue)
阻塞队列是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。
这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。
阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
BlockingQueue 核心方法(区别于Queue)
//将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,直到队列中有多余的空间。
void put(E e) throws InterruptedException;
//将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false.
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
//从队列中获取值,如果队列中没有值,线程会一直阻塞,直到队列中有值,并且该方法取得了该值。
E take() throws InterruptedException;
//在给定的时间里,从队列中获取值,如果没有取到会抛出异常。
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
//获取队列中剩余的空间。
int remainingCapacity();
//从队列中移除指定的值。
boolean remove(Object o);
//判断队列中是否拥有该值。
public boolean contains(Object o);
//将队列中值,全部移除,并发设置到给定的集合中。
int drainTo(Collection<? super E> c);
//指定最多数量限制将队列中值,全部移除,并发设置到给定的集合中。
int drainTo(Collection<? super E> c, int maxElements);
BlockingQueue的子类用法,详见Java中阻塞队列的使用
阻塞队列(LinkedBlockingQueue)和非阻塞队列(ConcurrentLinkedQueue)
1.LinkedBlockingQueue是使用锁机制,ConcurrentLinkedQueue是使用CAS算法,虽然LinkedBlockingQueue的底层获取锁也是使用的CAS算法
2.关于取元素,ConcurrentLinkedQueue不支持阻塞去取元素,LinkedBlockingQueue支持阻塞的take()方法。
3.关于插入元素的性能,但在实际的使用过程中,尤其在多cpu的服务器上,有锁和无锁的差距便体现出来了,ConcurrentLinkedQueue会比LinkedBlockingQueue快很多。
————————————————
版权声明:本文为CSDN博主「IT刘华强」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jiguquan3839/article/details/84342720
结语
最近发现工作中百度次数越来越多,发现自己的数据结构存在了很大问题。于是打算回过头重新把数据结构重新学习一下,于是结合网上的一些资源与自己的学习整理一下这方面的知识。