0
点赞
收藏
分享

微信扫一扫

生产者与消费者设计模式

1. 原理

它描述的是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者可以从仓库中取走产品,解决生产者/消费者问题,我们需要采用某种机制保护生产者和消费者之间的同步
同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性,常用的方法就是加锁,保证资源在任意时刻只被一个线程访问

画图分析:
生产者与消费者设计模式_ide

2. 实现

采用wait()、notify()和notifyAll()方法

wait():当缓冲区已满或空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等待状态,让其他线程执行

·是Object的方法
·调用方式:对象.wait();
·表示释放 对象 这个锁标记,然后在锁外边等待(对比sleep(),sleep是抱着锁休眠的)
·等待,必须放到同步代码段中执行
notify():当生产者/消费者向缓冲区放入/取出一个产品时,向其他等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态

·是Object的方法
·调用方式:对象.notify();
·表示唤醒 对象 所标记外边在等待的一个线程
notifyAll():全部唤醒

·是Object的方法
·调用方式:对象.notifyAll()
·表示唤醒 对象 所标记外边等待的所有线程

代码实现:

/**
* @author bruceliu
* @create 2019-06-01 22:04
* @description
*/
public class ProductorAndConsumerDemo01 {
// 定义一个标记,用来表示产品是否需要被生产
static boolean shouldProduct = true;

static Object o=new Object();

// 静态成员内部类
// 生产者线程的target
static class Productor implements Runnable {
//需要生产的产品
private Product p;

public Productor(Product p) {
this.p = p;
}


@Override
public void run() {
while (true) {
synchronized (o) {
if (shouldProduct) {
//生产
this.p.setName("老婆饼");
System.out.println("生产者" + Thread.currentThread().getName() + "生产了一件产品" + this.p);

//修改状态
shouldProduct = false;

//通知消费者来进行消费
o.notifyAll();
} else {
//等待
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}

//消费者线程的target
static class Consumer implements Runnable {
//需要被消费的产品
private Product p;

public Consumer(Product p) {
this.p = p;
}

@Override
public void run() {
while (true) {
synchronized (o) {
if (shouldProduct) {
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//消费
System.out.println("消费者" + Thread.currentThread().getName() + "消费了一件产品" + this.p);
//修改状态
shouldProduct = true;
//通知生产者去生产
o.notifyAll();
}
}
}
}
}

public static void main(String[] args) {
//说明:如果锁外面只有一个生产者或者一个消费者等待的话,则使用notify唤醒,
//但是,如果锁外面有多个生产者或者多个消费者等待的话,则使用notifyAll唤醒
//实例化一个产品
Product p = new Product();

//生产者
Productor productor = new Productor(p);
Thread t0 = new Thread(productor,"老王头");
Thread t1 = new Thread(productor,"老李头");
t0.start();
t1.start();

//消费者
Consumer consumer = new Consumer(p);
Thread thread0 = new Thread(consumer,"小凳子");
Thread thread1 = new Thread(consumer,"小桌子");
thread0.start();
thread1.start();

}
}

class Product {
private String name;
private int id;

public void setName(String name) {
this.name = name;
id++;
}

@Override
public String toString() {
return "Product [name=" + name + ", id=" + id + "]";
}
}


举报

相关推荐

0 条评论