首页 > 其他分享 >LinkedBlockingQueue和ArrayBlockingQueue对比

LinkedBlockingQueue和ArrayBlockingQueue对比

时间:2023-01-10 11:32:05浏览次数:36  
标签:capacity int lock ReentrantLock LinkedBlockingQueue new ArrayBlockingQueue 对比


对比一下LinkedBlockingQueue和ArrayBlockingQueue的区别。

1.底层数据结构不同

LinkedBlockingQueue底层是单向链表,只有一个后继指针

/**
* Linked list node class
*/
static class Node<E> {
E item;

/**
* One of:
* - the real successor Node
* - this Node, meaning the successor is head.next
* - null, meaning there is no successor (this is the last node)
*/
Node<E> next;

Node(E x) { item = x; }
}

ArrayBlockingQueue底层是数组

/** The queued items */
final Object[] items;

2.队列大小

LinkedBlockingQueue的构造函数,可以显示指定队列大小,也可以不指定,不指定大小事,默认是Integer.MAX_VALUE,可以观察他的三个构造函数:

public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}

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

public LinkedBlockingQueue(Collection<? extends E> c) {
this(Integer.MAX_VALUE);
final ReentrantLock putLock = this.putLock;
putLock.lock(); // Never contended, but necessary for visibility
try {
int n = 0;
for (E e : c) {
if (e == null)
throw new NullPointerException();
if (n == capacity)
throw new IllegalStateException("Queue full");
enqueue(new Node<E>(e));
++n;
}
count.set(n);
} finally {
putLock.unlock();
}
}

ArrayBlockingQueue的构造函数中,必须显示指定队列大小:

public ArrayBlockingQueue(int capacity) {
this(capacity, false);
}

public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}

public ArrayBlockingQueue(int capacity, boolean fair,
Collection<? extends E> c) {
this(capacity, fair);

final ReentrantLock lock = this.lock;
lock.lock(); // Lock only for visibility, not mutual exclusion
try {
int i = 0;
try {
for (E e : c) {
checkNotNull(e);
items[i++] = e;
}
} catch (ArrayIndexOutOfBoundsException ex) {
throw new IllegalArgumentException();
}
count = i;
putIndex = (i == capacity) ? 0 : i;
} finally {
lock.unlock();
}
}

3.使用的锁不同

LinkedBlockingQueue中,有两个锁,都是非公平锁:

/** Lock held by take, poll, etc */
private final ReentrantLock takeLock = new ReentrantLock();

/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();

ArrayBlockingQueue中,只有一个锁,默认是个非公平锁,也可以显示指定为公平锁:

/** Main lock guarding all access */
final ReentrantLock lock;
public ArrayBlockingQueue(int capacity) {
this(capacity, false);//默认是非公平锁
}

public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}

public ArrayBlockingQueue(int capacity, boolean fair,
Collection<? extends E> c) {
this(capacity, fair);

final ReentrantLock lock = this.lock;
lock.lock(); // Lock only for visibility, not mutual exclusion
try {
int i = 0;
try {
for (E e : c) {
checkNotNull(e);
items[i++] = e;
}
} catch (ArrayIndexOutOfBoundsException ex) {
throw new IllegalArgumentException();
}
count = i;
putIndex = (i == capacity) ? 0 : i;
} finally {
lock.unlock();
}
}


标签:capacity,int,lock,ReentrantLock,LinkedBlockingQueue,new,ArrayBlockingQueue,对比
From: https://blog.51cto.com/u_15936016/5999936

相关文章