/**
* synchronized+wait+noifty实现生产者消费者问题
* 分为消费者线程,生产者线程,缓冲区类,产品类
* 主要思想为生产者生产产品并放入缓冲取中,消费者从缓冲区中取出产品并消费
* 缓冲区中的数据要互斥访问,也就是说,对缓冲区的放入取出操作要用synchronized控制
* 另外要注意同步问题,即当缓冲区为空时,消费者不能取数据,当缓冲区满时,生产者不能放入数据,这个用wait控制
* 生产了数据或者消费了数据之后,用noifty唤醒消费线程取出数据或者生产线程即放入数据即可
* 关于缓冲区和产品的定义有点难以理解,我们是可以自己定义数组,如string[] arr
* */
package mypackage;
//产品,相当于生产的是什么,就是定义一个产品的类型,注意定义一个类,其实就可以作为类型使用,和int等没有本质区别
// 后面要用做创建数组的类型
class Product{
int id;
public Product(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer {
// 以产品类型定义一个产品数组,假如这里产品是牛肉,产品类就是Product类,将这个类实例化而已
Product[] beefs =new Product[100];
// 数组的下标,或者可以理解为数组中装入了多少产品
int count =0;
// 对缓冲区的压入产品操作,注意用了synchronized
public synchronized void push(Product beef){
// 如果产品数量等于数组容量就停止生产,等待
if(count==beefs.length){
try {
this.wait();
}catch (InterruptedException e){
}
}
// 否则开始生产,就是往数组中放牛肉,并且增加一个产品数量
beefs[count]=beef;
count++;
// 生产之后就有产品了,就可以唤醒消费者线程消费
this.notifyAll();
}
// 对缓冲区的取出产品操作,注意用了synchronized,并且因为有返回值,返回值的类型就是我们定义的Product
public synchronized Product pop(){
// 如果没有数据等待,不消费
if (count==0){
try {
this.wait();
}catch (InterruptedException e){
}
}
// 否则就进行消费,注意这里先count--
// 因为之前生产了数据之后,count++,但是此时的count指向的是填入产品后的下一个地方,而这个地方是没有产品的
// 因此先count--上移一位,定位到最后产品的位置,然后取出这个产品
count--;
Product beef=beefs[count];
// 取出产品之后就可以唤醒生产这线程进行生产了
this.notifyAll();
return beef;
}
}
//生产者
class Producer implements Runnable{
SynContainer container;
// 构造方法
public Producer(SynContainer container) {
this.container = container;
}
// 重写run方法
@Override
public void run() {
// 循环生产100次
for(int i=0;i<=100;i++){
System.out.println(Thread.currentThread().getName()+"生产第"+i+"块牛肉");
// 放入到缓冲区中,放入的就是一个编号而已
container.push(new Product(i));
}
}
}
//消费者
class Consumer implements Runnable{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
// 消费100次
for(int i=0;i<=100;i++){
System.out.println(Thread.currentThread().getName()+"消费第"+container.pop().id+"块牛肉");
}
}
}
public class ProducerConsumer {
public static void main(String[] args) {
// 实例化容器
SynContainer container=new SynContainer();
new Thread(new Producer(container),"生产者线程").start();
new Thread(new Consumer(container),"消费者线程").start();
}
}
Python 每日一记212>>>synchronized+wait+noifty实现生产者消费者问题
最新推荐文章于 2021-01-11 23:12:59 发布