您的位置:首页 > 其它

使用数组简单实现的阻塞队列

2017-08-17 15:13 441 查看
阻塞队列的定义:队列是一种先进先出的数据结构,如果队列为空,从队列中获取元素,消费者线程会阻塞,如果队列已经满了,生产者线程就会阻塞

这里使用lock锁和condition接口实现

代码如下:

package cn.erong.blockqueue;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* 使用数组实现阻塞队列
* @author zhouy
*
*/
public class ArrayBlockingQueue<T> {
private Lock lock = new ReentrantLock();
private Object[] item = new Object[4];
private int startIndex,endIndex,count;//初始化时,默认值为0,count 定义为队列中元素的数目
private Condition notfull = lock.newCondition();
private Condition notempty = lock.newCondition();
public void add(T t){
lock.lock();
try{
System.out.println("存放值"+t);
while(count==item.length){
try {
System.out.println("队列已满,阻塞put线程");
notfull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
item[startIndex++] = t;
count++;
if(startIndex==item.length){
startIndex=0;
}
notempty.signal();
}finally{
lock.unlock();
}
}

public T take(){
lock.lock();//获取锁不能写在try块中,如果发生异常,锁会被释放
try{
while(count==0){
try {
System.out.println("队列空了,阻塞take线程");
notempty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t =(T)item[endIndex++];
System.out.println("取值"+t);
count--;
if(endIndex==item.length){
endIndex = 0;
}
notfull.signal();
return t;
}finally{
lock.unlock();
}
}
}

可以简单的测试一下:
package cn.erong.blockqueue;

public class BlockTest {
public static void main(String[] args) {
//启动一个子线程,不断的生产元素
final ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<3;i++){
queue.add(i);
}
}
});
try {
thread.join();
thread.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程不断的获取,显然最后,主线程会阻塞
for(int i=0;i<15;i++){
queue.take();
}
}
}
结果如下:
队列空了,阻塞take线程

存放值0

存放值1

存放值2

取值0

取值1

取值2

队列空了,阻塞take线程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息