/***
* 使用condition来实现阻塞队列
*/
public class Demo_Condition_BlockQueue {
public static void main(String[] args) throws InterruptedException{
DuanQueue bb=new DuanQueue(5);
new Thread() {
@Override
public void run() {
for (int i = 0; i < 15; i++) {
bb.put("x" + i);
}
}
}.start();
Thread.sleep(3000L);
System.out.println("开始从队列中取元素...");
for(int i=0;i<15;i++){
bb.take();
Thread.sleep(3000L);
}
}
}
/***
* 1.自己实现一个阻塞队列,只能存储n个元素,put时,若队列未满,直接put
* 若队列满,就阻塞,直到再有空间
* 2.get时,若队列中有元素,则获取到元素,如无元素,则等待元素
*/
class DuanQueue{
List<Object> list=new ArrayList<>();
Lock lock=new ReentrantLock();
Condition putCondition=lock.newCondition();
Condition takeConditon=lock.newCondition();
private int lenth;
public DuanQueue(int lenth) {
this.lenth = lenth;
}
public void put(Object object){
lock.lock();
try{
for(;;){
if(list.size()<lenth){
list.add(object);
System.out.println("put:" + object);
takeConditon.signal();
break;
}else {
putCondition.await();//todo 使用自旋模式,如果被唤醒则进行再次put操作,如果不用自旋模式则putCondition被唤醒后直接跳出
//put操作就失效了
}
}
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public Object take(){
lock.lock();
Object object=null;
try {
for(;;){
if(list.size()>0){
object=list.get(0);
list.remove(0);
System.out.println("take: "+object);
putCondition.signal();
break;
}else {
takeConditon.await();//todo 使用自旋方式,如果该线程被唤醒,则再次进行从队列中获取元素操作,如果不用自旋模式则被唤醒后直接跳出
//本次take 操作就获取不到数据了
}
}
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
return object;
}
}
使用condition来实现阻塞队列
最新推荐文章于 2024-07-28 14:57:22 发布
本文介绍了一种使用自旋模式的阻塞队列实现方法。通过自定义的DuanQueue类,利用ReentrantLock和Condition实现了线程间的同步控制。当队列满时,put操作将进入自旋等待;当队列为空时,take操作同样采用自旋等待,直至条件满足。
摘要由CSDN通过智能技术生成