参考文献

BlockingQueue

  • BlockingQueue是Java中的一个接口,用于在多线程环境下实现线程间的安全数据交换.它通常用于生产者-消费者场景,其中一个线程负责向队列中放入对象,另一个线程负责从队列中取出对象.
  • 在这个场景中,生产线程会不断地创建新对象并将其插入到队列中,直到队列达到其容量上限.一旦队列达到临界点,生产线程在尝试插入新对象时会被阻塞.它会一直等待,直到消费线程从队列中取走一个对象.消费线程则会一直从队列中取出对象.如果消费线程尝试从空队列中提取对象,它也会被阻塞,直到生产线程将一个对象放入队列中.
  • BlockingQueue的实现类有多种,包括ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue等.不同的实现类有着不同的特性和适用场景,但它们都遵循上述的基本原理.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public interface BlockingQueue<E> extends Queue<E> {
/**
* Inserts the specified element into this queue if it is possible to do so
* immediately without violating capacity restrictions, returning
* {@code true} upon success and throwing an {@code IllegalStateException}
* if no space is currently available.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Collection#add})
* @throws IllegalStateException if the element cannot be added at this
* time due to capacity restrictions
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null and
* this queue does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this queue
*/
boolean add(E e);

/**
* Inserts the specified element into this queue if it is possible to do
* so immediately without violating capacity restrictions.
* When using a capacity-restricted queue, this method is generally
* preferable to {@link #add}, which can fail to insert an element only
* by throwing an exception.
*
* @param e the element to add
* @return {@code true} if the element was added to this queue, else
* {@code false}
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this queue
* @throws NullPointerException if the specified element is null and
* this queue does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this queue
*/
boolean offer(E e);

void put(E e) throws InterruptedException;

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);

boolean contains(Object o);

int drainTo(Collection<? super E> c);

int drainTo(Collection<? super E> c, int maxElements);
}
接口/行为 抛出异常 返回特定值 一直阻塞 阻塞一段时间
新增元素 add(e) offer(e) put(e) offer(e,time,unit)
删除元素 remove() poll() take() poll(time,unit)
查看元素 element() peek() / /
  • 行为的解释
    • 抛出异常: 如果试图的操作无法立即执行,抛一个异常.
    • 返回特定值: 如果试图的操作无法立即执行,返回一个特定的值(常常是 true / false).
    • 一直阻塞: 如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行.
    • 阻塞一段时间: 如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过

BlockingDeque

  • java.util.concurrent 包里的 BlockingDeque 接口表示一个线程安全放入和提取实例的双端队列.
  • BlockingDeque类是一个双端队列,在不能够插入元素时,它将阻塞住试图插入元素的线程;在不能够抽取元素时,它将阻塞住试图抽取的线程. deque(双端队列) 是 “Double Ended Queue” 的缩写.因此,双端队列是一个你可以从任意一端插入或者抽取元素的队列.
  • 在线程既是一个队列的生产者又是这个队列的消费者的时候可以使用到 BlockingDeque.如果生产者线程需要在队列的两端都可以插入数据,消费者线程需要在队列的两端都可以移除数据,这个时候也可以使用 BlockingDeque
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public interface BlockingDeque<E> extends BlockingQueue<E>, Deque<E> {
/*
* We have "diamond" multiple interface inheritance here, and that
* introduces ambiguities. Methods might end up with different
* specs depending on the branch chosen by javadoc. Thus a lot of
* methods specs here are copied from superinterfaces.
*/
void addFirst(E e);

void addLast(E e);

boolean offerFirst(E e);

boolean offerLast(E e);

void putFirst(E e) throws InterruptedException;

void putLast(E e) throws InterruptedException;

boolean offerFirst(E e, long timeout, TimeUnit unit)
throws InterruptedException;

boolean offerLast(E e, long timeout, TimeUnit unit)
throws InterruptedException;

E takeFirst() throws InterruptedException;

E takeLast() throws InterruptedException;

E pollFirst(long timeout, TimeUnit unit)
throws InterruptedException;

E pollLast(long timeout, TimeUnit unit)
throws InterruptedException;

boolean removeFirstOccurrence(Object o);

boolean removeLastOccurrence(Object o);

// *** BlockingQueue methods ***

boolean add(E e);

boolean offer(E e);

void put(E e) throws InterruptedException;

boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;

E remove();

E poll();

E take() throws InterruptedException;

E poll(long timeout, TimeUnit unit)
throws InterruptedException;

E element();

E peek();

boolean remove(Object o);

boolean contains(Object o);

int size();

Iterator<E> iterator();

// *** Stack methods ***

void push(E e);
}
接口/行为 抛出异常 返回特定值 一直阻塞 阻塞一段时间
插入元素 addFirst(o) offerFirst(o) putFirst(o) offerFirst(o, timeout, timeunit)
移除元素 removeFirst(o) pollFirst(o) takeFirst(o) pollFirst(timeout, timeunit)
检查元素 getFirst(o) peekFirst(o) / /
接口/行为 抛出异常抛异常 返回特定值特定值 一直阻塞阻塞 阻塞一段时间超时
插入元素 addLast(o) offerLast(o) putLast(o) offerLast(o, timeout, timeunit)
移除元素 removeLast(o) pollLast(o) takeLast(o) pollLast(timeout, timeunit)
检查元素 getLast(o) peekLast(o) / /
  • BlockingDequeBlockingQueue 接口的方法对比

    BlockingQueue BlockingDeque
    add() addLast()
    offer() offerLast()
    put() putLast()
    remove() removeFirst()
    poll() pollFirst()
    take() takeFirst()
    element() getFirst()
    peek() peekFirst()