BlockingQueue接口
一、了解什么是阻塞队列
在一个队列中,存在两种阻塞的情况,如下图:
二、接口常用的子类
BlockingQueue四组API方法汇总
BlockingQueue四组API①
会抛出异常的方式
添加数据用add,移除数据用remove方法
具体的代码如下:
public class Test {
public static void main(String[] args) {
test01();
}
/*1、抛出异常的API解决方案*/
public static void test01() {
//创建一个队列,里面的参数3是队列的大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
//调用add方法,往队列中存值
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
//Queue full:由于队列的大小只有3,传第四个值就会抛出异常
System.out.println(blockingQueue.add("d"));
System.out.println("------------------");
//调用remove方法,遵循FIFO(先进先出)原则,弹出队列中的数据
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
//NoSuchElementException:由于队列中没有元素了已经,再remove就会抛异常
System.out.println(blockingQueue.remove());
}
}
查看队列中队首的元素
System.out.println(blockingQueue.element()); //查看队首的元素(a)
BlockingQueue四组API②
不抛出异常,并且能够获得返回值,如果存取值超出队列的大小,那么就会返回一个值,不会抛出异常,如果企业中需要这个业务,使用这个解决方案即可
代码如下:
public class Test {
public static void main(String[] args) {
test02();
}
/*2、不抛出异常,并且可以有返回值*/
public static void test02(){
ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
//存数据用offer
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d")); //队列大小只有3,往里面再存数据不会抛异常,返回一个布尔类型的false
System.out.println("===========");
//取数据用poll
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());//队列中的数据只有3个,弹出3个数据后还执行poll,返回一个Null,不抛异常
}
}
查看队首元素:
System.out.println(blockingQueue.peek()); //查看队首的元素(a)
BlockingQueue四组API③
如果队列满了或者移除的时候没有这个元素,那么他就会一直处于阻塞状态,程序不会停止
代码如下:
public class Test {
public static void main(String[] args) throws InterruptedException {
test03();
}
/*3、队列满了时候,一直阻塞*/
public static void test03() throws InterruptedException {
ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
//存数据用put
blockingQueue.put("a"); //无返回值
blockingQueue.put("b");
blockingQueue.put("c");
//blockingQueue.put("d"); //此时队列3个位置都没有空余,那么他就会一直等待,程序不会执行结束
//移除数据用take
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take()); //现在队列中已经没有这个元素了,那么他就会一直处于等待阻塞状态
}
}
BlockingQueue四组API④
如果队列满了,此时会发生阻塞,但是可以存在阻塞超时,超时后就不再等待
代码如下:
public class Test {
public static void main(String[] args) throws InterruptedException {
test04();
}
/*4、队列满了,保持阻塞等待状态,但是会有等待超时,超时就结束等待
* 使用的是解决方案2中的存取数据的重载方法*/
public static void test04() throws InterruptedException {
ArrayBlockingQueue<Object> 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(blockingQueue.offer("d",2, TimeUnit.SECONDS)); //队列只能存3个元素,存第四个元素的时候会阻塞等待2秒钟,然后就会返回一个true或者false
System.out.println("===================");
//移除元素用poll的重载方法,前三个数据可以正常移除,而最后一个元素等待2秒,返回能否成功移除
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS)); //移除第四个,因为队列中不存在,等待2秒钟,再返回结果
}
}