LinkedBlockingQueue源码分析(一)

简介:
LinkedBlockingQueue是一个基于链表结构的阻塞队列;队列元素遵循先进先出的原则(FIFO);
新成员被添加到队列的尾部。链表队列比起数组队列(例如ArrayBlockingQueue)来说,一般具有
更高的吞吐量,但其性能在大多数并发应用程序中,比较难预测(less predictable performance in most concurrent applications)。

一、成员变量
1、内部类
/** * Linked list node class */ static class Node<E> { E item; Node<E> next; Node(E x) { item = x; } }
定义了队列的最小存储单元,所以LinkedBlockingQueue底层的存储结构是一个链表。
2、int capacity
队列的大小,默认为int最大值。
3、AtomicInteger count
当前存储的元素个数。因为这个值是随着对队列的操作不断需要改变的,所以使用了int的线程安全类AtomicInteger。
4、Node head
队列的头部节点。
5、Node last
队列的尾部节点。
6、ReentrantLock takeLock 、Condition notEmpty
两个成员构成一把完整的“读”锁。
7、ReentrantLock putLock、Condition notFull
两个成员构成一把完整的“写”锁。
二、构造函数

 public LinkedBlockingQueue(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node<E>(null);
    }

LinkedBlockingQueue有多个构造函数,但其他的构造函数都会首先调用这个构造函数进行初始化(capacity默认会传入int的最大值)。
LinkedBlockingQueue会初始化一个空节点,然后头部和尾部指针都会指向它。

三、主要方法
1、put方法

public void put(E e) throws InterruptedException {
			if (e == null) throw new NullPointerException();
			int c = -1;
			Node<E> node = new Node<E>(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 < capacity)
					notFull.signal();
			} finally {
				putLock.unlock();
			}
			if (c == 0)
				signalNotEmpty();
		}

1.1putLock保证当前只会有一个线程在往队列中写值;
1.2从while循环那里可以看出,put方法的特点是当向队列写入的时候,如果队列已满,会一直阻塞在那里,等待其他线程来唤醒。
备注:notFull.signal()方法会随机唤醒一个等待中的线程,而非全部;notFull.await()被唤醒后,方法本身会尝试重新去获取锁。
由于等待和唤醒的动作都在同一个方法内,所以即使队列中的元素被取出,阻塞的写入线程也不会马上执行,它需要等待其他的写入线程来唤醒(极端的情况,可能一直没有向队列写入的动作,那么那些以前阻塞的线程会一直阻塞在那里----即使现在队列是空的),这种设计会对队列的性能有所影响,使用时要根据自己的业务场景选择合适的队列和方法。
2、enqueue方法
。。。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值