您的位置:首页 > 产品设计 > UI/UE

经典的生产者与消费者模型(基于BlockingQueue队列实现)

2017-07-31 08:46 726 查看
基于BlockingQueue实现与之前的基于synchronized方法实现的不同,这里不需要单独创建仓库类,用队列替代仓库,简化编程。



BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种:
1. 当队列满了的时候进行入队列操作
2. 当队列空了的时候进行出队列操作


负责生产的线程不断的制造新对象并插入到阻塞队列中,直到达到这个队列的上限值。队列达到上限值之后生产线程将会被阻塞,直到消费的线程对这个队列进行消费。同理,负责消费的线程不断的从队列中消费对象,直到这个队列为空,当队列为空时,消费线程将会被阻塞,除非队列中有新的对象被插入。


实现代码如下:

package queue.producer.consumer;

import java.util.concurrent.*;

/**
* 生产者与消费者
* @author tiger
* @Date 2017年7月27日
*/
public class ProducerAndConsumerQueue {
public static void main(String[] args) throws InterruptedException {
//替代仓库类
BlockingQueue queue  = new ArrayBlockingQueue(20);

Producer pro1 = new Producer(queue);
Producer pro2 = new Producer(queue);
Salesman con = new Salesman(queue);

Thread make1 = new Thread(pro1,"1号生产机器");//生产者线程 1 号
Thread make2 = new Thread(pro2,"2号生产机器");//生产者线程 2 号

Thread cons1 = new Thread(con,"老鼠销售员1");//销售员线程1
Thread cons2 = new Thread(con,"老虎销售员2");//销售员线程2
Thread cons3 = new Thread(con,"蓝猫销售员3");//销售员线程3
Thread cons4 = new Thread(con,"兔子销售员4");//销售员线程4
Thread cons5 = new Thread(con,"小红销售员5");//销售员线程5

make1.start();
make2.start();
cons1.start();
cons2.start();
cons3.start();
cons4.start();
cons5.start();
}
}
package queue.producer.consumer;

import java.util.concurrent.*;
/**
* 生产者
* @author tiger
* @Date 2017年7月28日
*/
class Producer implements Runnable{
//持有队列,类似于仓库
final BlockingQueue queue ;

public Producer(BlockingQueue queue) {
this.queue = queue;
}
public void productGoods(){
//货物ID
int ran = (int) (Math.random()*1000);
//生产者名称
String name = Thread.currentThread().getName();
String id = String.valueOf(ran);
try {
queue.put(id);
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产货物
System.out.println(name+" 生产一个货物["+id+"],现在货物数量" + queue.size());
}
@Override
public void run() {
//仓库只要没有满就一直不停在生产货物
while (true) {
productGoods();
//模拟每个货物生产需要花费的时间
try {
TimeUnit.MICROSECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package queue.producer.consumer;

import java.util.concurrent.*;
/**
* 销售员
* @author tiger
* @Date 2017年7月27日
*/
class Salesman implements Runnable{
//代替了面包店
final BlockingQueue queue ;
public Salesman(BlockingQueue queue) {
this.queue = queue;
}

public void sellGoods(){
String name = Thread.currentThread().getName();
try {
String id = queue.take();
System.out.println(name+" 卖掉一个货物["+id+"],现在货物数量" + queue.size());
System.out.println("------------------------------");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public void run() {
//仓库只要有货物就一直不停卖
while (true) {
sellGoods();
//模拟卖一个货物所需要花费的时间
try {
TimeUnit.MICROSECONDS.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: