您的位置:首页 > 其它

使用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);
}

}


弄完之后对线程有了一个更深的理解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息