生产者消费者模型
多个线程操作统一资源,但是多个线程的功能是不一样的
场景:一个生产者、一个消费者
最终目的:生产一个、消费一个
分析:产品类Phone、生产者线程类Producer、消费者线程类Consumer
Demo
package producer_consumer;
public class Demo {
public static void main(String[] args) {
/*
* 多个线程操作统一资源,并且每个线程的功能不一样 --> 生产者消费者模型 / 仓储模型
* 场景:一个生产者、一个消费者
* 最终目的:生产一个、消费一个
* 步骤:
* 1.生产者线程和消费者线程操作同一个资源
* 脏数据: null--00.0
* 产品1--1000.0
* 2.两个产品来回切换(让步骤一的脏数据更明显)
* 脏数据: null--00.0
* 产品1--1000.0
* 产品2--1000.0
* 产品1--3000.0
* 解决方案:加锁 -> 生产者在生产过程中,消费者线程不能输出
* 脏数据:00.0 -> 生产者还没生产完一个产品,消费者就抢到资源消费了
* 3.生产一个、消费一个 -> 生产者线程和消费者线程来回切换
* 1)生产者生产完一个产品,就进入阻塞状态,唤醒消费者
* 2)消费者消费完一个产品,就进入阻塞状态,唤醒生产者
*/
Phone phone = new Phone();
Producer producer = new Producer(phone);
Consumer consumer = new Consumer(phone);
producer.start();
consumer.start();
}
}
Product类
package producer_consumer;
public class Phone {
private String name;
private double price;
private boolean status;//假设一开始没有库存
public Phone() {
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public Phone(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Producer线程类
package producer_consumer;
/**
* 生产者线程
*/
public class Producer extends Thread{
private Phone phone;
public Producer(Phone phone) {
this.phone = phone;
}
@Override
public void run() {
boolean flag = true;//生产产品转换
while(true){
synchronized (phone) {
if(phone.isStatus()){//有库存
try {
phone.wait();//等待:1.将当前线程记录到对象监视器中 2.释放锁资源 3.当前线程进入到阻塞状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(flag){
phone.setName("华为");
phone.setPrice(3999);
System.out.println("生产了:" + phone.getName() + "--" + phone.getPrice());
}else{
phone.setName("小米");
phone.setPrice(1999);
System.out.println("生产了:" + phone.getName() + "--" + phone.getPrice());
}
flag = !flag;
phone.setStatus(true);
phone.notify();//唤醒
}
}
}
}
Consumer线程类
package producer_consumer;
/**
* 消费者线程
*/
public class Consumer extends Thread{
private Phone phone;
public Consumer(Phone phone) {
this.phone = phone;
}
@Override
public void run() {
while(true){
synchronized (phone) {
if(!phone.isStatus()){//没有库存
try {
phone.wait();//等待:1.将当前线程记录到对象监视器中 2.释放锁资源 3.当前线程进入到阻塞状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费了:" + phone.getName() + " -- " + phone.getPrice());
phone.setStatus(false);
phone.notify();//唤醒:唤醒对象监视器中随机的线程
}
}
}
}
场景:多个生产者、多个个消费者
最终目的:生产者生产多少产品,消费者消费多少产品
分析:产品类Product、生产者线程类Producer、消费者线程类Consumer
Demo
package producer_consumer_2;
public class Demo {
public static void main(String[] args) {
/*
* 多个线程操作统一资源,并且每个线程的功能不一样 --> 生产者消费者模型 / 仓储模型
* 场景:多个生产者、多个消费者
* 最终目的:生产一个、消费一个
* 步骤:
* 1.生产者线程和消费者线程操作同一个资源
* 脏数据: null--00.0
* 产品1--1000.0
* 2.两个产品来回切换(让步骤一的脏数据更明显)
* 脏数据: null--00.0
* 产品1--1000.0
* 产品2--1000.0
* 产品1--3000.0
* 解决方案:加锁 -> 生产者在生产过程中,消费者线程不能输出
* 脏数据:00.0 -> 生产者还没生产完一个产品,消费者就抢到资源消费了
* 3.生产一个、消费一个 -> 生产者线程和消费者线程来回切换
* 1)生产者生产完一个产品,就进入阻塞状态,唤醒消费者
* 2)消费者消费完一个产品,就进入阻塞状态,唤醒生产者
*/
Phone phone = new Phone();
Producer producer1 = new Producer(phone);
Producer producer2 = new Producer(phone);
Consumer consumer1 = new Consumer(phone);
Consumer consumer2 = new Consumer(phone);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
}
}
Product类
package producer_consumer_2;
public class Phone {
private String name;
private double price;
private boolean status;//假设一开始没有库存
public Phone() {
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public Phone(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Producer线程类
package producer_consumer_2;
/**
* 生产者线程
*/
public class Producer extends Thread{
private Phone phone;
private static boolean flag = true;//生产产品转换,设置为静态变量->统一多个生产者的标准
public Producer(Phone phone) {
this.phone = phone;
}
@Override
public void run() {
while(true){
synchronized (phone) {
//一个一个排除,如果有库存->生产者都阻塞,如果没有库存->消费者都阻塞
while (phone.isStatus()){//有库存
try {
phone.wait();//等待:1.将当前线程记录到对象监视器中 2.释放锁资源 3.当前线程进入到阻塞状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(flag){
phone.setName("华为");
phone.setPrice(3999);
System.out.println("生产了:" + phone.getName() + "--" + phone.getPrice());
}else{
phone.setName("小米");
phone.setPrice(1999);
System.out.println("生产了:" + phone.getName() + "--" + phone.getPrice());
}
flag = !flag;
phone.setStatus(true);
phone.notifyAll();//唤醒:唤醒对象监视器中所有的线程
}
}
}
}
Consumer线程类
package producer_consumer_2;
/**
* 消费者线程
*/
public class Consumer extends Thread{
private Phone phone;
public Consumer(Phone phone) {
this.phone = phone;
}
@Override
public void run() {
while(true){
synchronized (phone) {
while (!phone.isStatus()){//没有库存
try {
phone.wait();//等待:1.将当前线程记录到对象监视器中 2.释放锁资源 3.当前线程进入到阻塞状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费了:" + phone.getName() + " -- " + phone.getPrice());
phone.setStatus(false);
phone.notifyAll();//唤醒:唤醒对象监视器中所有的线程
}
}
}
}