• 生产者消费者模型+仓储模型及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();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    //消费者线程
    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();
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    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 + "]";
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    //生产者线程
    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();
    			}
    			
    		}
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    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();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    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 + "]";
    	}	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    //消费者线程
    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();
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    //生产者线程
    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
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    二、仓储模型

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

    分析:

    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();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    //蛋糕类
    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 ;
    	}		
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    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();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    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);
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    //消费者线程
    public class Consumer extends Thread{
    
    	private Store store;
    
    	public Consumer(Store store) {
    		this.store = store;
    	}
    	
    	@Override
    	public void run() {
    		while (true) {
    			store.pop();
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    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();
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    //蛋糕类
    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;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    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();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    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);
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    //消费者线程
    public class Consumer extends Thread{
    	
    	private Store store;
    	
    	public Consumer(Store store) {
    		this.store = store;
    	}
    
    	@Override
    	public void run() {
    		while(true){
    			store.pop();
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    三、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();
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    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();
    	}
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    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());
    		
    	}	
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    联邦学习的梯度重构
    搬到新办公室,开始新征程
    美食杰项目重难点记录
    后视镜为什么要检测反射率
    Linux:系统安全及应用
    vscode中快速生成vue3模板
    java和数据库之间的关系,看这一篇就足够~~~
    yolo训练时遇到GBK编码问题
    Laya---横向滚动列表
    L1-003 个位数统计
  • 原文地址:https://blog.csdn.net/GL280599ZL/article/details/127624921