首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java集合之阻塞队列LinkedBlockingQueue

LinkedBlockingQueue是一种阻塞队列,有队列的基本功能,并且带有阻塞的功能,先看下类的继承关系

LinkedBlockingQueue

队列中的每个元素是一个Node,Node有个变量next指向下一个元素,定义如下:

static class Node {

E item;

Node next;

Node(E x) { item = x; }

}

看下怎么入队一个元素put(E e),

1,检查添加的元素是否为空,如果为空,抛出异常

2、创建一个新的Node对象

3、获取一个putLock可中断的锁

4、如果队列已满等待,如果没满就把元素加入队列,把添加前队列数量加1比容量小,唤醒等待的线程

5,释放锁,如果添加元素前队列为空,现在有元素了,唤醒出队等待的线程

public void put(E e) throws InterruptedException {

if (e == null) throw new NullPointerException();

int c = -1;

Node node = new Node(e);

final ReentrantLock putLock = this.putLock;

final AtomicInteger count = this.count;

putLock.lockInterruptibly();

try {

while (count.get() == capacity) {

notFull.await();

}

enqueue(node);

c = count.getAndIncrement();

if (c + 1

notFull.signal();

} finally {

putLock.unlock();

}

if (c == 0)

signalNotEmpty();

}

下面看看入队的操作enqueue(node),很简单,把node赋值给last的next,并把node 赋值给last。

private void enqueue(Node node) {

last = last.next = node;

}

看下出队的操作take()

1、获取一个takeLock可中断的锁

2、如果队列为空,等待

3、如果不为空,从队列取一个元素

4、如果取出元素后,队列中还有,唤醒等待线程

5、释放锁,如果取出元素前队列是满的,现在取出了一个,队列不是满的了,唤醒入队等待的线程

public E take() throws InterruptedException {

E x;

int c = -1;

final AtomicInteger count = this.count;

final ReentrantLock takeLock = this.takeLock;

takeLock.lockInterruptibly();

try {

while (count.get() == 0) {

notEmpty.await();

}

x = dequeue();

c = count.getAndDecrement();

if (c > 1)

notEmpty.signal();

} finally {

takeLock.unlock();

}

if (c == capacity)

signalNotFull();

return x;

}

现在看看出队的方法dequeue(),把head的next取出来,并且把head指向head的next。

private E dequeue() {

Node h = head;

Node first = h.next;

h.next = h; // help GC

head = first;

E x = first.item;

first.item = null;

return x;

}

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200210A0R46F00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券