本文意在通过图形化的形式展示LinkedBlockingQueue在Clear操作时数据结构的变化。

准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class LinkedBlockingQueueTest {
private LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
@Before
public void setUp() {
try {
queue.put(10);
queue.put(20);
queue.put(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void testClear(){
queue.clear();
}
}

创建一个阻塞队列,然后进行清空;

源码

LinkedBlockingQueue Clear()源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Atomically removes all of the elements from this queue.
* The queue will be empty after this call returns.
*/
public void clear() {
fullyLock();
try {
for (Node<E> p, h = head; (p = h.next) != null; h = p) {
h.next = h;
p.item = null;
}
head = last;
// assert head.item == null && head.next == null;
if (count.getAndSet(0) == capacity)
notFull.signal();
} finally {
fullyUnlock();
}
}

过程演示

Step-1 新建队列:

Step1

Step-2 执行初始化语句Node<E> p, h = head;:

Step-2

Step-3 执行条件判断语句(p = h.next) != null;:

Step-3

Step-4 执行循环体中h.next = h;:

Step-4

Step-5 执行循环体中p.item = null;:

Step-5

Step-6 执行控制条件语句h = p:

Step-6

Step-7 执行循环体直至最后一个节点:

Step-7

Step-8 执行语句head = last;:

Setp8

将head、last都指向空节点,触发notFull条件,以便插入线程添加元素,至此队列的清空操作完成。