明确主体
什么是 阻塞队列?
这次我们讨论的主体是 BlockingQueue ,他是一个interface(接口)
尝试思考 阻塞队列 的使用场景。
- 多线程开发
- 线程池
四组API(存取)
通过对 阻塞队列 的 “存”、“取”,来了解 BlockingQueue 的四组 API:
方式 | 抛出异常 | 不抛异常 | 阻塞等待 | 限时等待 |
---|---|---|---|---|
添加 | add(E e) | offer(E e) | put(E e) | offer(E e,long time,TimeUnit unit) |
移除 | remove() | poll() | take() | poll(long time, TimeUnit unit) |
判断队列首 | element() | peek() | - | - |
借助BlockingQueue的实现类 ArrayBlockingQueue来体验一下这四组API:
创建阻塞队列:
//构建阻塞队列——队列容量为 3
//使用不公平 Lock 锁,(为了延续UPC的线程调度策略)
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(3,false);
抛出异常的:
/**
* 抛出异常
*/
System.out.println(queue.add("S"));
System.out.println(queue.add("K"));
System.out.println(queue.add("Y"));
//java.lang.IllegalStateException: Queue full
//System.out.println(queue.add("FUcK!"));
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
//java.util.NoSuchElementException
//System.out.println(queue.remove());
不抛异常的:
/**
* 不抛出异常
*/
System.out.println(queue.offer("S"));
System.out.println(queue.offer("K"));
System.out.println(queue.offer("Y"));
// 打印 false,,不抛异常!
System.out.println(queue.offer("F*Ck!"));
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
//打印 null,没取到(不抛异常!)
System.out.println(queue.poll());
一直阻塞的:
/**
* 一直阻塞
*/
queue.put("S");//无返回值
queue.put("K");
queue.put("Y");
System.out.println("开始等待 ~ ~ ~");
queue.put("我呵呵,等着吧!");
System.out.println(queue.element());
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println("拿不着,我不走 !!!");
System.out.println(queue.take());
程序会一直在这“卡” 着,直到 “存进去” 或 “取出来” 才会往下执行。
限时等待:
/**
* 限时等待
*/
//存
// 参数: 值 ,数值 ,单位(时间)
System.out.println(queue.offer("S",1L, TimeUnit.SECONDS));//————等一秒钟,等不到位置,就返回 false
System.out.println(queue.offer("K",1L, TimeUnit.SECONDS));//————等一秒钟,等不到位置,就返回 false
System.out.println(queue.offer("Y",1L, TimeUnit.SECONDS));//————等一秒钟,等不到位置,就返回 false
System.out.println(queue.offer("wait",1L, TimeUnit.SECONDS));//————等一秒钟,等不到位置,就返回 false
System.out.println(queue.peek());
//取
// 参数: 数值 ,单位(时间)
System.out.println(queue.poll(1L,TimeUnit.SECONDS));//————等一秒钟,等不到值,就返回 null
System.out.println(queue.poll(1L,TimeUnit.SECONDS));//————等一秒钟,等不到值,就返回 null
System.out.println(queue.poll(1L,TimeUnit.SECONDS));//————等一秒钟,等不到值,就返回 null
System.out.println(queue.poll(1L,TimeUnit.SECONDS));//————等一秒钟,等不到值,就返回 null
补充
常用散列集关系图