本文共 1214 字,大约阅读时间需要 4 分钟。
By 翻译:寒桐 校对:方腾飞
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:
从5.0开始,JDK在java.util.concurrent包里提供了阻塞队列的官方实现。尽管JDK中已经包含了阻塞队列的官方实现,但是熟悉其背后的原理还是很有帮助的。
阻塞队列的实现类似于带上限的Semaphore的实现。下面是阻塞队列的一个简单实现
01 | public class BlockingQueue { |
02 |
03 | private List queue = new LinkedList(); |
04 |
05 | private int limit = 10 ; |
06 |
07 | public BlockingQueue( int limit){ |
08 |
09 | this .limit = limit; |
10 |
11 | } |
12 |
13 | public synchronized void enqueue(Object item) |
14 |
15 | throws InterruptedException { |
16 |
17 | while ( this .queue.size() == this .limit) { |
18 |
19 | wait(); |
20 |
21 | } |
22 |
23 | if ( this .queue.size() == 0 ) { |
24 |
25 | notifyAll(); |
26 |
27 | } |
28 |
29 | this .queue.add(item); |
30 |
31 | } |
32 |
33 | public synchronized Object dequeue() |
34 |
35 | throws InterruptedException{ |
36 |
37 | while ( this .queue.size() == 0 ){ |
38 |
39 | wait(); |
40 |
41 | } |
42 |
43 | if ( this .queue.size() == this .limit){ |
44 |
45 | notifyAll(); |
46 |
47 | } |
48 |
49 | return this .queue.remove( 0 ); |
50 |
51 | } |
52 |
53 | } |
必须注意到,在enqueue和dequeue方法内部,只有队列的大小等于上限(limit)或者下限(0)时,才调用notifyAll方法。如果队列的大小既不等于上限,也不等于下限,任何线程调用enqueue或者dequeue方法时,都不会阻塞,都能够正常的往队列中添加或者移除元素。
转载地址:http://ncufm.baihongyu.com/