使用Lock与ReentrantLock模拟消息队列阻塞,生产与消费问题模拟
2017-06-12 20:47
591 查看
//测试结果 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; }*/ @Override public 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; } @Override public void run() { eggs.addEgg(eggName); } }
弄完之后对线程有了一个更深的理解
相关文章推荐
- 使用 ReentrantLock 和 Condition 实现一个阻塞队列
- java中使用阻塞队列实现生产这与消费这之间的关系
- java 使用ReentrantLock Condition实现阻塞队列
- java中使用阻塞队列解决生产者消费者问题
- Java多线程之生产者消费者问题<三>:使用阻塞队列更优雅地解决生产者消费者问题
- 阻塞队列实现--生产消费模型
- 后台程序使用SystemV消息队列遇到的资源泄漏问题
- 使用lock和condition实现的阻塞队列-字符串
- 使用消息队列读取模拟量的值
- synchronized/wait/notify 与 mutex/cond wait wake ~ 链表队列 生产消费问题
- 使用notiy和wait模拟阻塞队列
- ActiveMQ使用线程池实现消息的生产与消费
- ActiveMQ使用线程池实现消息的生产与消费
- Linux定时器处理之实时信号使用,消息队列阻塞模型,避免超时等待
- RocketMQ使用P2P(点对点)消息传送模式,生产端生产一个消息,消费端消费几乎同时收到两个相同消息
- 使用阻塞队列解决生产者-消费者问题
- java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)
- 单生产单消费多生产多消费问题的解决及使用机制
- Posix消息队列使用非阻塞mq_receive的信号通知
- ActiveMQ使用线程池实现消息的生产与消费 .