使用Lock与ReentrantLock模拟消息队列阻塞,生产与消费问题模拟

来源:互联网 发布:大众奥迪编程 编辑:程序博客网 时间:2024/06/02 03:07
//测试结果package com.cn.test.queue;public class EggTest {/** * @param args */public static void main(String[] args) {//创建一个鸡蛋篮子,实现阻塞队列EggBlockingQueue eggs=new EggBlockingQueue();int n=0;PutEggThread put=null;PollEggThread poll=null;//创建10个放鸡蛋如篮子的线程while(n<10){put=new PutEggThread();put.setEggs(eggs);put.setEggsName(n);put.start();n++;}n=0;//创建10个拿鸡蛋的线程while(n<10){poll=new PollEggThread();poll.setEggs(eggs);poll.start();n++;}}}


package com.cn.test.queue;import java.util.ArrayDeque;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantLock;public class EggBlockingQueue {//数组队列用来存放鸡蛋@SuppressWarnings("rawtypes")private  ArrayDeque aq=new ArrayDeque();private  ReentrantLock lock;private  Condition notFull;private  Condition notEmpty;public EggBlockingQueue(){lock=new ReentrantLock();notFull=lock.newCondition();notEmpty=lock.newCondition();}/** * 取出鸡蛋 * @return the eggname */public void pollEgg() {final ReentrantLock lock=this.lock;//获取锁lock.lock();try {if (aq.size()<=0) {System.out.println("鸡蛋已经拿完了,等待放入鸡蛋");}//当鸡蛋篮子为空的时候,当前线程进入等待队列while(aq.size()<=0){notFull.await();}System.out.println("从篮子里拿出来的鸡蛋是......"+(String)aq.poll());}catch (InterruptedException e1) {e1.printStackTrace();//唤醒等待线程队列里的线程
notEmpty.signal();
}finally{//释放对象锁lock.unlock();}}/** * 放入鸡蛋 * @param eggname the eggname to set */public void addEgg(String eggname) {final ReentrantLock lock=this.lock;//获取锁try {lock.lockInterruptibly();//鸡蛋篮子容量只能放放5个//超出5个就进入等待状态while(aq.size()>=5){notEmpty.awaitNanos(500);}System.out.println("放入篮子里的鸡蛋是......"+eggname+"是否放入成功"+aq.add(eggname));}catch (InterruptedException e) {System.out.println("唤醒拿鸡蛋的线程........");//唤醒等待线程队列里的线程
notFull.signal();
}finally{//释放对象锁lock.unlock();}}}


package com.cn.test.queue;public class PollEggThread extends Thread {private EggBlockingQueue eggs;//private String eggName;public void setEggs(EggBlockingQueue args) {eggs=args;}/*public void setEggsName(int args){eggName="Eggs-"+args;}*/@Overridepublic void run() {eggs.pollEgg();}}

package com.cn.test.queue;public class PutEggThread extends Thread {private EggBlockingQueue eggs;private String eggName;public void setEggs(EggBlockingQueue args) {eggs=args;}public void setEggsName(int args){eggName="Eggs-"+args;}@Overridepublic void run() {eggs.addEgg(eggName);}}


弄完之后对线程有了一个更深的理解