LinkedBlockingQueue的源码解析(基于JDK1.8)

LinkedBlockingQueue的源码解析(基于JDK1.8)

LinkedBlockingQueue是Java集合框架中的一个阻塞队列实现类,它是线程安全的,支持高并发操作。本文将对LinkedBlockingQueue的源码进行解析,基于JDK1.8版本。

基本介绍

LinkedBlockingQueue是一个基于链表实现的阻塞队列,它具有以下特点:

  • 队列容量可选,默认为Integer.MAX_VALUE。
  • 链表节点有一个前驱节点和一个后继节点,可以快速的添加、删除、检索元素。
  • 队列支持两种模式:公平模式和非公平模式。在公平模式下,线程按照FIFO顺序竞争访问队列;在非公平模式下,线程可以随意竞争访问队列。
  • 阻塞队列支持put()和take()方法,分别用于添加元素和获取元素。当队列满时,put()方法会阻塞等待;当队列空时,take()方法会阻塞等待。

源码解析

变量定义

LinkedBlockingQueue的源码定义了以下变量:

transient Node<E> first;
transient Node<E> last;
private final int capacity;
private final ReentrantLock takeLock = new ReentrantLock();
private final Condition notEmpty = takeLock.newCondition();
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = putLock.newCondition();

其中,first和last分别表示链表的头结点和尾节点;capacity表示队列容量;takeLock和putLock则是两个ReentrantLock类型的锁,用于控制take()和put()方法的并发访问。notEmpty和notFull则是两个Condition类型的条件变量,用于控制阻塞等待的线程。

节点定义

LinkedBlockingQueue的节点定义如下:

static class Node<E> {
    E item;
    Node<E> next;
    Node(E x) { item = x; }
}

节点包含一个元素和一个指向下一个节点的指针。每个节点都是一个独立的实体,可以单独进行操作,例如添加、删除、检索等。

添加元素

LinkedBlockingQueue的add()方法用于向队列中添加元素,源码如下:

public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("Queue full");
}

add()方法内部调用了offer()方法,如果offer()方法返回true,则表示添加成功,直接返回true;如果offer()方法返回false,则表示队列已满,抛出IllegalStateException异常。

offer()方法的源码如下:

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    final ReentrantLock putLock = this.putLock;
    putLock.lock();
    try {
        while (count == capacity) {
            notFull.await();
        }
        insert(e);
        return true;
    } finally {
        putLock.unlock();
    }
}

offer()方法首先获取putLock锁,然后判断队列是否已满。如果队列已满,则将当前线程阻塞在notFull条件变量上,等待其他线程从队列中取出元素,以便腾出空间。insert()方法用于将元素添加到队列尾部。最后,释放putLock锁。

获取元素

LinkedBlockingQueue的take()方法用于从队列中获取元素,源码如下:

public E take() throws InterruptedException {
    final ReentrantLock takeLock = this.takeLock;
    takeLock.lockInterruptibly();
    try {
        while (count == 0) {
            notEmpty.await();
        }
        return extract();
    } finally {
        takeLock.unlock();
    }
}

take()方法首先获取takeLock锁,然后判断队列是否为空。如果队列为空,则将当前线程阻塞在notEmpty条件变量上,等待其他线程向队列中添加元素。extract()方法用于从队列头部获取元素。最后,释放takeLock锁。

总结

LinkedBlockingQueue是一个高性能、线程安全的阻塞队列实现类,它的源码实现了链表节点的添加、删除、检索等基本操作。在多线程并发访问时,它使用了ReentrantLock和Condition等线程同步机制,保证了线程安全性和高并发性能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过分的规定

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值