生产者消费者模型+仓储模型及Java自带的线程池

生产者消费者模型+仓储模型及Java自带的线程池

一、生产者消费者模型

1.注意:一个生产者一个消费者

2.最终目的:生产一个、消费一个

3.分析:

1.产品类 – Phone

2.生产者线程 – Producer

3.消费者线程 – Consumer

4.步骤:

步骤1:生产者线程和消费者线程操作同一个资源

步骤2:在两个产品之间切换(目的:将步骤1的问题扩大化)

步骤3:如何生产一个消费一个?

public class Test01 {

	public static void main(String[] args) {
		
		Phone phone = new Phone();
		
		Producer p = new Producer(phone);
		Consumer c = new Consumer(phone);
		
		p.start();
		c.start();
	}
}
//消费者线程
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.isStore()) {//没有库存
					try{
						//等待
						phone.wait();
					}catch (InterruptedException e){
						e.printStackTrace();
					}
				}
				System.out.println(phone.getBrand() + " -- " + phone.getPrice());
				phone.setStore(false);
				
				//唤醒
				phone.notify();
			}
		}
	}
}
public class Phone {

	private String brand;
	private double price;
	private boolean isStore;
	
	public Phone() {
	}

	public Phone(String brand, double price) {
		this.brand = brand;
		this.price = price;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	
	public boolean isStore() {
		return isStore;
	}

	public void setStore(boolean isStore) {
		this.isStore = isStore;
	}

	@Override
	public String toString() {
		return "Phone [brand=" + brand + ", price=" + price + "]";
	}	
}
//生产者线程
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.isStore()) {//有库存
					
					try{
						//等待(1.当前线程进入到阻塞状态 2.将当前线程记录在对象监视器中 3.释放锁资源)
						phone.wait();
					}catch(InterruptedException e){
						e.printStackTrace();
					}
				}
				if (flag) {
					phone.setBrand("华为");
					phone.setPrice(3999);
				} else {
					phone.setBrand("小米");
					phone.setPrice(1999);
				}
				phone.setStore(true);
				flag = !flag;
				
				//唤醒(对象监视器中可能记录了很多等待的线程,这里唤醒的是随机一个线程)
				phone.notify();
			}
			
		}
	}
	
}

5.多个生产者多个消费者的情况

if变为while

notify() 变为 notifyAll()

public class Test01 {

	public static void main(String[] args) {
		
		Phone phone = new Phone();
		
		Producer p1 = new Producer(phone);
		Producer p2 = new Producer(phone);
		
		Consumer c1 = new Consumer(phone);
		Consumer c2 = new Consumer(phone);
		
		p1.start();
		p2.start();
		c1.start();
		c2.start();
	}
}
public class Phone {

	private String brand;
	private double price;
	private boolean isStore;
	
	public Phone() {
	}

	public Phone(String brand, double price) {
		this.brand = brand;
		this.price = price;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public boolean isStore() {
		return isStore;
	}

	public void setStore(boolean isStore) {
		this.isStore = isStore;
	}

	@Override
	public String toString() {
		return "Phone [brand=" + brand + ", price=" + price + "]";
	}	
}
//消费者线程
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.isStore()) {//没有库存
					try {
						//等待
						phone.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(phone.getBrand()+ " -- " + phone.getPrice());
				phone.setStore(false);
				
				//唤醒
				phone.notifyAll();
			}
		}
	}
}
//生产者线程
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.isStore()) {//有库存
					
					try {
						//等待(1.当前线程进入到阻塞状态 2.将当前线程记录在对象监视器中 3.释放锁资源)
						phone.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				if (flag) {
					phone.setBrand("华为");
					phone.setPrice(3999);
				}else {
					phone.setBrand("小米");
					phone.setPrice(1999);
				}
				phone.setStore(true);
				flag = !flag;
				
				//唤醒(对象监视器中可能记录了很多等待的线程,这里唤醒的是所有等待的线程)
				phone.notifyAll();
			}		
		}
	}
}

二、仓储模型

需求:生产者线程不断的生产蛋糕放入仓库,消费者不断的从仓库中买蛋糕,要求先生产的蛋糕先卖出(队列)

分析:

1.蛋糕类

2.仓库类

3.生产者线程类

4.消费者线程类

1.一个生产者一个消费者的情况

public class Test01 {

	public static void main(String[] args) {
		
		Store store = new Store();
		
		Producer p = new Producer(store);
		Consumer c = new Consumer(store);
		
		p.start();
		c.start();
	}
}

//蛋糕类
public class Cake {

	private String brand;
	private double price;
	private String dateTime;
	
	public Cake() {
	}

	public Cake(String brand, double price, String dateTime) {
		super();
		this.brand = brand;
		this.price = price;
		this.dateTime = dateTime;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public String getDateTime() {
		return dateTime;
	}

	public void setDateTime(String dateTime) {
		this.dateTime = dateTime;
	}

	@Override
	public String toString() {
		return  brand + "\t" + price + "\t" + dateTime ;
	}		
}

import java.util.LinkedList;
//仓库类
public class Store {

	//面包容器
	private LinkedList<Cake> list;
	//当前面包容量
	private int curCapacity;
	//最大面包容量
	private static final int MAX_CAPACITY = 20;
	
	public Store() {
		 list = new LinkedList<>();
	} 
	
	//入库 -- 生产者线程去调用
	public synchronized void push(Cake cake){
		if (curCapacity == MAX_CAPACITY) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		curCapacity++;
		list.add(cake);
		System.out.println("入库,当前面包容量为:" + curCapacity);
		
		this.notify();
	}
	
	//出库 -- 消费者线程去调用
	public synchronized void pop(){
		if (curCapacity == 0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		curCapacity--;
		Cake cake = list.removeFirst();
		System.out.println("出库,当前面包容量为:" + curCapacity + " -- " + cake);
		
		this.notify();
	}
}

import java.time.LocalDateTime;
//生产者线程
public class Producer extends Thread{

	private Store store;

	public Producer(Store store) {
		this.store = store;
	}
	
	@Override
	public void run() {
		while (true) {
			Cake cake = new  Cake("桃李面包", 4.5, LocalDateTime.now().toString());
			store.push(cake);
		}
	}
}

//消费者线程
public class Consumer extends Thread{

	private Store store;

	public Consumer(Store store) {
		this.store = store;
	}
	
	@Override
	public void run() {
		while (true) {
			store.pop();
		}
	}
}

2.多个生产者多个消费者的情况

public class Test01 {
	public static void main(String[] args) {
		
		Store store = new Store();
		
		Producer p1 = new Producer(store);
		Producer p2 = new Producer(store);
		Consumer c1 = new Consumer(store);
		Consumer c2 = new Consumer(store);
		
		p1.start();
		p2.start();
		c1.start();
		c2.start();
		
	}
}

//蛋糕类
public class Cake {
	
	private String brand;
	private double price;
	private String dateTime;
	
	public Cake() {
	}

	public Cake(String brand, double price, String dateTime) {
		this.brand = brand;
		this.price = price;
		this.dateTime = dateTime;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public String getDateTime() {
		return dateTime;
	}

	public void setDateTime(String dateTime) {
		this.dateTime = dateTime;
	}

	@Override
	public String toString() {
		return brand + "\t" + price + "\t" + dateTime;
	}
}

import java.util.LinkedList;

//仓库类
public class Store {

	//面包容器
	private LinkedList<Cake> list;
	//当前面包容量
	private int curCapacity;
	//最大面包容量
	private static final int MAX_CAPACITY = 20;
	
	public Store() {
		list = new LinkedList<>();
	}
	
	//入库 -- 生产者线程去调用
	public synchronized void push(Cake cake){
		while(curCapacity == MAX_CAPACITY){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		curCapacity++;
		list.add(cake);
		System.out.println("入库,当前面包容量为:" + curCapacity);
		
		this.notifyAll();
	}
	
	//出库 -- 消费者线程去调用
	public synchronized void pop(){
		while(curCapacity == 0){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		curCapacity--;
		Cake cake = list.removeFirst();
		System.out.println("出库,当前面包容量为:" + curCapacity + " -- " + cake);
		
		this.notifyAll();
	}
}

import java.time.LocalDateTime;

//生产者线程
public class Producer extends Thread{
	
	private Store store;
	
	public Producer(Store store) {
		this.store = store;
	}

	@Override
	public void run() {
		while(true){
			Cake cake = new Cake("桃李面包", 4.5, LocalDateTime.now().toString());
			store.push(cake);
		}
	}
}

//消费者线程
public class Consumer extends Thread{
	
	private Store store;
	
	public Consumer(Store store) {
		this.store = store;
	}

	@Override
	public void run() {
		while(true){
			store.pop();
		}
	}
}

三、Java自带的线程池

使用Java自带的线程池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test01 {

	public static void main(String[] args) {
		//创建单个线程的线程池
		//ExecutorService pool = Executors.newSingleThreadExecutor();
		//创建指定个数线程的线程池
		//ExecutorService pool = Executors.newFixedThreadPool(5);
		//创建可缓存线程的线程池(该线程池中没有线程,有任务就创建线程,60s没有执行任务的线程认为是闲置线程,会被销毁掉
		ExecutorService pool = Executors.newCachedThreadPool();
		for (int i = 1; i <=1000; i++) {
			//创建任务
			Task task = new Task(i);
			//提交任务
			pool.execute(task);
		}
		//关闭线程池
		pool.shutdown();
	}
}

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test02 {

	public static void main(String[] args) {
		//创海可缓存线程的线程池(该线程池中没有线程,有任务就创建线程,60s没有执行任务的线程认为是闲置线程,会被销毁掉)
		ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);
		
		for (int i = 1; i <=1000; i++) {
			//创建任务
			Task task = new Task(i);
			/**
			 * 提交任务
			 * 参数1:提交的任务对象
			 * 参数2:延迟时间
			 * 参数3:时间类型
			 */
			pool.schedule(task, 5L, TimeUnit.SECONDS);
		}
		//关闭线程池
		pool.shutdown();
	}
}


import java.time.LocalDateTime;

public class Task implements Runnable{
	//任务编号
	private int num;
	
	public Task(int num) {
		this.num = num;
	}


	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "-------" + num + "---" + LocalDateTime.now());
		
	}	
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨霖先森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值