LinkedBlockingQueue简介
LinkedBlockingQueue是使用独占锁实现的阻塞队列,内部是通过单向链表实现的,使用头、尾节点来进行入队和出队操作,也就是入队操作都是对尾节点进行操作,出队操作都是对头节点进行操作。
主要的方法介绍
- offer(E e)
向队列尾部插入一个元素,如果队列中有空闲则插入成功后返回 true,如果队列己满 则丢弃当前元素然后返回 false。 如果e元素为null则抛出NPE异常。
- put(E e)
向队列尾部插入一个元素,如果队列中有空闲则插入后直接返回,如果队列己满则阻塞当前线程,直到队列有空闲插入成功后返回。如果在阻塞时被其他线程设置了中断标志, 则被阻塞线程会抛出 InterruptedException 异常而返回。另外,如e元素为null则抛出 NPE 异常。
- poll()
从队列头部获取并移除一个元素,如果队列为空则返回 null,该方法是不阻塞的。
- peek()
从队列头部获取元素但不移除它,如果队列为空则返回 null。 该方法是不阻塞的。
- take()
获取当前队列头部元素并从队列里面移除它。 如果队列为空则阻塞当前线程直到队列 不为空然后返回元素,如果在阻塞时被其他线程设置了中断标志,则被阻塞线程会抛出 InterruptedException 异常而返回。
- size()
获取当前队列元素个数。由于进行出队、入队操作时的 count是加了锁的,所以结果相比ConcurrentLinkedQueue 的 size 方法比较准确。
- remove()
删除队列里面指定的元素,有则删除并返回 true,没有则返回 false。
示例代码:
本示例是一个生产者与消费者的例子,演示LinkedBlockingQueue的使用方法,设定一个生成者最多生产3辆汽车。
public class BlockingQueueTest { // 定义汽车生产者 static class Producer implements Runnable { private String name; private BlockingQueue<String> storehouse; public Producer(String name, BlockingQueue<String> storehouse) { this.name = name; this.storehouse = storehouse; } public void run() { try { int i=1; while (true) { // 生产汽车 System.out.println(name+"准备生产汽车"); storehouse.put(name+"[汽车"+i+"]"); System.out.println(name+"生产汽车"+i+"完成"); Thread.sleep(500); i++; if(i==4){ break; } } } catch (InterruptedException ex) { ex.printStackTrace(); } } } // 定义汽车消费者 static class Consumer implements Runnable { private String name; private BlockingQueue<String> storehouse; public Consumer(String name, BlockingQueue<String> storehouse) { this.name = name; this.storehouse = storehouse; } public void run() { try { while (true) { // 消费汽车 System.out.println(name+"准备消费汽车"); System.out.println(name+"消费的汽车是:"+storehouse.take()); System.out.println(name+"消费汽车完毕:"); // 休眠1000ms Thread.sleep(1000); } } catch (InterruptedException ex) { ex.printStackTrace(); } } } public static void main(String[] args) { //定义一个存放汽车的仓库,最大存放3辆汽车 BlockingQueue<String> storehouse = new LinkedBlockingQueue<String>(3); Producer producer = new Producer("生产者1", storehouse); new Thread(producer).start(); Producer producer2 = new Producer("生产者2", storehouse); new Thread(producer2).start(); Consumer consumer = new Consumer("消费者", storehouse); new Thread(consumer).start(); } }
运行结果如下:
从结果可以看出,当消费者线程从队列消费完所有的汽车以后就进入阻塞状态。同时也可以看出生产和消费是可以同时进行的,即入队和出队操作是可以同时进行的。
如果觉得本文对您有些许的帮助,还请帮忙关注、点赞或转发,非常感谢!!!