概念
-
队列遵循FIFO原则,即first input first output 先进先出原则。
-
阻塞队列
- 写入(put):如果队列满了就必须阻塞等待。
- 取(take): 如果队列是空的,就必须阻塞等待生产。
-
关于BlockingQueueAPI如下
-
阻塞队列 BlockQueue 是Collection 的一个子类(应用场景:多线程并发处理、线程池)
阻塞队列常用方法
方式 | 抛出异常 | 不会抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add | offer | put | offer(timenum,timeUnit) |
移出 | remove | poll | take | poll(timenum,timeUnit) |
判断队首元素 | element | peek | - |
下面的示例通过junit进行单元测试,需要导入如下依赖。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
示例一 抛出异常的增加和移除方法
@Test
public void test01(){
//实例化一个长度为3的队列
ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
System.out.println(blockingQueue.element());//a 抛出 队首
//如果添加第4个及以上元素就会抛出异常 java.lang.IllegalStateException: Queue full
System.out.println(blockingQueue.remove());//a 取出的时候遵循先进先出
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
//如果再移除一个,就会造成 java.util.NoSuchElementException
}
//结果 true true true a a b c
示例二 不抛出异常的增加和移除方法
@Test
public void test02(){
ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3)
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
//添加第4个元素及以上不会抛出异常,返回false
System.out.println(blockingQueue.offer("d"));
System.out.println(blockingQueue.peek());//打印对首元素
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
//移除第四个元素及以上不会抛出异常,返回null
System.out.println(blockingQueue.poll());
}
//结果:true true true false a a b c null
示例三 阻塞等待(一直等待)
@Test
public void test03() throws InterruptedException {
ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
//一直阻塞,第4个值不会添加成功
//blockingQueue.put("c");
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
//一直阻塞,取不出第4个值
//System.out.println(blockingQueue.take());
}
示例4 超时等待(过时不候,超过时间就不等待)
@Test
public void test04() throws InterruptedException {
ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println("开始等待");
System.out.println(blockingQueue.offer("d", 2, TimeUnit.SECONDS));
System.out.println("等待结束");
System.out.println("=================取值=====================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println("取值开始等待");
System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));//超过两秒,我们就不等待了
System.out.println("取值结束等待");
}
结果
true
true
true
开始等待
false
等待结束
=================取值=====================
a
b
c
取值开始等待
null
取值结束等待