文章目录
简介主要属性入队列出队列总结
简介
ArrayBlockingQueue是采用数组实现的有界阻塞线程安全队列 。 线程安全是指,ArrayBlockingQueue内部通过“互斥锁”保护竞争资源,实现了多线程对竞争资源的互斥访问。
主要属性
final Object
[] items
;
int takeIndex
;
int putIndex
;
int count
;
final ReentrantLock lock
;
private final Condition notEmpty
;
private final Condition notFull
;
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 void put(E e
) throws InterruptedException
{
checkNotNull(e
);
final ReentrantLock lock
= this.lock
;
lock
.lockInterruptibly();
try {
while (count
== items
.length
)
notFull
.await();
enqueue(e
);
} finally {
lock
.unlock();
}
}
private void enqueue(E x
) {
final Object
[] items
= this.items
;
items
[putIndex
] = x
;
if (++putIndex
== items
.length
)
putIndex
= 0;
count
++;
notEmpty
.signal();
}
public boolean offer(E e
) {
checkNotNull(e
);
final ReentrantLock lock
= this.lock
;
lock
.lock();
try {
if (count
== items
.length
)
return false;
else {
enqueue(e
);
return true;
}
} finally {
lock
.unlock();
}
}
public boolean add(E e
) {
return super.add(e
);
}
public boolean add(E e
) {
if (offer(e
))
return true;
else
throw new IllegalStateException("Queue full");
}
出队列
public E
take() throws InterruptedException
{
final ReentrantLock lock
= this.lock
;
lock
.lockInterruptibly();
try {
while (count
== 0)
notEmpty
.await();
return dequeue();
} finally {
lock
.unlock();
}
}
private E
dequeue() {
final Object
[] items
= this.items
;
@SuppressWarnings("unchecked")
E x
= (E
) items
[takeIndex
];
items
[takeIndex
] = null
;
if (++takeIndex
== items
.length
)
takeIndex
= 0;
count
--;
if (itrs
!= null
)
itrs
.elementDequeued();
notFull
.signal();
return x
;
}
总结
ArrayBlockingQueue利用takeIndex和putIndex循环利用数组。
队列长度固定并且必须在初始化时指定。
如果出队列速度跟不上入队速度,则会导致入队线程一直阻塞。
只使用了一个锁来控制入队操作与出队操作,效率较低。