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等线程同步机制,保证了线程安全性和高并发性能。