JUC 详解 -> BlockingQueue
1. BlockingQueue阻塞队列
- 阻塞
- 队列 FIFO
- 写入:如果队列满了,就必须阻塞等待
- 取:如果队列是空的,必须阻塞等待生产
什么情况下使用阻塞队列?
多线程并发处理;线程池!
-
使用队列?
- 添加;
- 移除
2. BlockingQueue四组API
方式 | 抛出异常 | 不会抛出异常,有返回值 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add(E e) | offer(E e) | put() | offer(E e, long timeout, TimeUnit unit) |
移除 | remove() | poll() | take() | poll(long timeout, TimeUnit unit) |
检测队首元素 | element() | peek() | —— | —— |
-
抛出异常
import java.util.concurrent.ArrayBlockingQueue; public class BlockingQueueTest { public static void main(String[] args) { test01(); } /** * 1、抛出异常 */ public static void test01(){ //队列大小 ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); //返回true System.out.println(blockingQueue.add("a")); System.out.println(blockingQueue.add("b")); System.out.println(blockingQueue.add("c")); //java.lang.IllegalStateException: Queue full 抛出异常! //System.out.println(blockingQueue.add("d")); //查看队首元素, 返回a System.out.println(blockingQueue.element()); //按FIFO(a-b-c)弹出 System.out.println(blockingQueue.remove()); //查看队首元素, 返回b System.out.println(blockingQueue.element()); System.out.println(blockingQueue.remove()); System.out.println(blockingQueue.remove()); //java.util.NoSuchElementException 抛出异常 System.out.println(blockingQueue.remove()); }
-
有返回值,不抛出异常
import java.util.concurrent.ArrayBlockingQueue; public class BlockingQueueTest { public static void main(String[] args) { test02(); } /** * 2、有返回值,不抛出异常 */ public static void test02(){ ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); //返回true System.out.println(blockingQueue.offer("a")); System.out.println(blockingQueue.offer("b")); System.out.println(blockingQueue.offer("c")); //检测队首元素 返回a System.out.println(blockingQueue.peek()); //返回false,不抛出异常 System.out.println(blockingQueue.offer("d")); //按FIFO a-b-c弹出 System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); //返回null,抛出异常 System.out.println(blockingQueue.poll()); } }
-
阻塞等待
import java.util.concurrent.ArrayBlockingQueue; public class BlockingQueueTest { public static void main(String[] args) throws InterruptedException { test03(); } /** * 3、等待,阻塞(一直阻塞) */ public static void test03() throws InterruptedException { ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); //添加,无返回值 blockingQueue.put("a"); blockingQueue.put("b"); blockingQueue.put("c"); //队列满了,没有位置了,一直阻塞 //blockingQueue.put("d"); //按FIFO a-b-c拿出元素 System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); System.out.println(blockingQueue.take()); //队列空了,没有元素了,一直阻塞 System.out.println(blockingQueue.take()); } }
-
超时等待
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; public class BlockingQueueTest { public static void main(String[] args) throws InterruptedException { test04(); } /** * 4、等待,阻塞(等待超时) */ //offer() 和 poll()的重载方法 public static void test04() throws InterruptedException { ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3); blockingQueue.offer("a"); blockingQueue.offer("b"); blockingQueue.offer("c"); //blockingQueue.offer("d",2, TimeUnit.SECONDS); //等待超过2秒,就退出 System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); System.out.println(blockingQueue.poll()); blockingQueue.poll(2,TimeUnit.SECONDS); //等待超过2秒,就退出 } }