普通阻塞队列
除了刚介绍的两个队列,其他队列都是阻塞队列,都实现了接口BlockingQueue,在入队/出队时可能等待,主要方法有:
入队,如果队列满,等待直到队列有空间
void put(E e) throws InterruptedException;
出队,如果队列空,等待直到队列不为空,返回头部元素
E take() throws InterruptedException;
入队,如果队列满,最多等待指定的时间,如果超时还是满,返回false
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
出队,如果队列空,最多等待指定的时间,如果超时还是空,返回null
E poll(long timeout, TimeUnit unit) throws InterruptedException;
普通阻塞队列是常用的队列,常用于生产者/消费者模式。
ArrayBlockingQueue和LinkedBlockingQueue都实现了Queue接口,表示先进先出的队列,尾部进,头部出,而LinkedBlockingDeque实现了Deque接口,是一个双端队列。
ArrayBlockingQueue是基于循环数组实现的,有界,创建时需要指定大小,且在运行过程中不会改变,这与我们在容器类中介绍的ArrayDeque是不同的,ArrayDeque也是基于循环数组实现的,但是是无界的,会自动扩展。
LinkedBlockingQueue是基于单向链表实现的,在创建时可以指定最大长度,也可以不指定,默认是无限的,节点都是动态创建的。LinkedBlockingDeque与LinkedBlocking-Queue一样,最大长度也是在创建时可选的,默认无限,不过,它是基于双向链表实现的。
内部,它们都是使用显式锁ReentrantLock和显式条件Condition实现的。
ArrayBlockingQueue的实现很直接,有一个数组存储元素,有两个索引表示头和尾,有一个变量表示当前元素个数,有一个锁保护所有访问,有“不满”和“不空”两个条件用于协作与ArrayBlockingQueue类似,LinkedBlockingDeque也是使用一个锁和两个条件,使用锁保护所有操作,使用“不满”和“不空”两个条件。
LinkedBlockingQueue稍微不同,因为它使用链表,且只从头部出队、从尾部入队,它做了一些优化,使用了两个锁,一个保护头部,一个保护尾部,每个锁关联一个条件。
了解更多Java知识,可以点击下方链接和小编一起学习哟~