阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
以下所有测试使用的队列长度为3
一、抛出异常
1.添加:add()
使用add()方法向队列中添加元素,若多添加,会报java.lang.IllegalStateException: Queue full异常。
public class Test {
public static void main(String[] args) {
test1();
}
//抛出异常
public static void test1() {
ArrayBlockingQueue 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.add("d"));
}
}
2.移除:remove()
使用remove()方法向队列中移除元素,若多移除,会报java.util.NoSuchElementException异常。
public class Test {
public static void main(String[] args) {
test1();
}
//抛出异常
public static void test1() {
ArrayBlockingQueue 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.remove();
blockingQueue.remove();
blockingQueue.remove();
blockingQueue.remove();
}
}
二、有返回值,不抛出异常
1.添加:offer()
使用offer()方法向队列中添加元素,若多添加,会返回false。
public class Test {
public static void main(String[] args) {
test2();
}
//有返回值,不抛出异常
public static void test2() {
ArrayBlockingQueue 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.移除:poll()
使用poll()方法向队列中移除元素,若多移除会返回null
public class Test {
public static void main(String[] args) {
test2();
}
//有返回值,不抛出异常
public static void test2() {
ArrayBlockingQueue 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.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
}
三、阻塞等待
1.添加:put()
使用put()方法向队列中添加元素,若多添加,就会阻塞,一直等待下去。
public class Test {
public static void main(String[] args) throws InterruptedException {
test3();
}
//阻塞等待
public static void test3() throws InterruptedException {
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
blockingQueue.put("d");
}
}
2.移除:take()
使用take()方法向队列中移除元素,若多移除会一直等待。
public class Test {
public static void main(String[] args) throws InterruptedException {
test3();
}
//阻塞等待
public static void test3() throws InterruptedException {
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
System.out.println("===============");
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
}
}
四、超时等待
1.添加:offer(E e, long timeout, TimeUnit unit)
使用offer()方法向队列中添加元素,设置超时时间,若多添加且超过时间,会返回false。
public class Test {
public static void main(String[] args) throws InterruptedException {
test4();
}
//超时等待
public static void test4() throws InterruptedException {
ArrayBlockingQueue 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));
}
}
2.移除:poll()
使用poll()方法向队列中移除元素,设置超时时间,若多移除且超过时间会返回null
public class Test {
public static void main(String[] args) throws InterruptedException {
test4();
}
//超时等待
public static void test4() throws InterruptedException {
ArrayBlockingQueue 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.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));
}
}