扒一扒阻塞队列的实现

1.主要结构 一个用于存放元素的数组

两个Condition 用于阻塞 唤醒 线程

2.代码

public class MyBelokingQueue<E> implements Serializable{

//用于存放元素的数组

Object[] item;

 

/** 下一个put的索引, offer, or add */

int putIndex;

 

/** 队列中元素的数量 */

int count;

/**下一个获取元素的下标**/

int takeIndex;

 

Condition notEmty;

Condition notNull;

ReentrantLock reentrantLock;

 

public void MyBelokingQueue(int index){

if(index<=0){

throw new IllegalArgumentException();

}

this.item=new Object[index];

this.reentrantLock=new ReentrantLock();

this.notEmty=reentrantLock.newCondition();

this.notNull=reentrantLock.newCondition();

}

 

@Override

public void put(E e) throws InterruptedException {

checkNotNull(e);

final ReentrantLock lock = this.lock;

lock.lockInterruptibly(); //可中断的获取锁

try {

while (count == items.length)//当线程从等待中被唤醒时,会比较当前队列是否已经满了

{notFull.await();}//这里可以看到 当数组满了  notFull 就会让当前线程阻塞

enqueue(e);//插入队列的方法

} finally {

lock.unlock();

}

}

 

}

 

public void enqueue(E e){

final Object[] items = this.item;

items[putIndex]=e;

//如果当前索引等于数组长度那么 下次从0开始

if(++putIndex==items.length){

putIndex=0;

}

count++; //总数加1

notEmty.signal();//唤醒线程

}

//检查是否是null

public void checkNotNull(E e){

if(e==null){

throw new NullPointerException();

}

}

/**

**************获取元素 take(): 检索并且删除返回队列头的元素,如果元素没有会一直等待,有就返回。

@Override

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;//设置该下标元素为null

if (++takeIndex == items.length)

{takeIndex = 0;}

count--;

if (itrs != null)

{itrs.elementDequeued();}

notFull.signal(); //当元素被消费  队列不满了 就唤醒等待put的线程

return x;

}

 

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值