线程5-生产者消费者模式(线程通信)
package com.thread.test; /** * 1、生产者生产出产品,给商店(缓冲区) 2、商店把产品提供给消费者 * (1)需要三个角色,生产者,商店,消费者 * (2)涉及到多线程 * (3)涉及到线程安全 * (4)线程间通信 */ class Producer implements Runnable{ private Store store; public Producer(Store store){ this.store = store; } @Override public void run() { System.out.println("开始生产=="); while(true){ try { Thread.currentThread(); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } store.addProduct(Thread.currentThread().getName()); } } } class Store{ int product = 1; //生产 public synchronized void addProduct(String name){ if(product >= 20){ try { wait();//当产品大于20时,释放对象锁 } catch (InterruptedException e) { e.printStackTrace(); } }else{ product++; System.out.println(name+"正在生产 "+product+" 号产品"); notifyAll();//生产完后,唤醒所有线程,可能唤醒一个消费线程也可能唤醒一个生产线程, //当唤醒生产线程时,生产线程获取对象锁,(注意,此时消费线程获取不到对象锁,无法消费),产品数量仍大于20,仍然进入等待状态 //唤醒消费线程时,消费线程获取对象锁,(注意,此时不生产,因为生产线程没有锁),消费线程就去消费 } } //消费 public synchronized void reduceProduct(String name){ if(product <= 0){ try { wait();//当产品小于0时,等待,释放对象锁,重新去等待获取消费的机会 } catch (InterruptedException e) { e.printStackTrace(); } }else{ System.out.println(name + "正在消费 "+ product+" 产品"); product -- ; notifyAll();//消费完后,唤醒所有线程,可能唤醒一个消费线程也可能唤醒一个生产线程, //当唤醒消费线程时,消费线程获取对象锁,(注意,此时生产线程获取不到对象锁,无法生产),仍然进入等待状态 //唤醒生产线程时,生产线程获取对象锁,(注意,此时不消费),生产线程就去生产 } } } class Consumer implements Runnable{ private Store store; public Consumer(Store store){ this.store = store; } @Override public void run() { while(true){ try { Thread.currentThread(); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } store.reduceProduct(Thread.currentThread().getName()); } } } public class 生产者消费者模式 { public static void main(String[] args) { Store store = new Store(); Producer producer = new Producer(store); Consumer consumer = new Consumer(store); Thread p1 = new Thread(producer);//生产者1 Thread p2 = new Thread(producer);//生产者2 p1.setName("1号生产者"); p2.setName("2号生产者"); Thread c1 = new Thread(consumer);//消费者1 c1.setPriority(Thread.MAX_PRIORITY);//设置线程权重,提升被cpu执行的机会 c1.setName("1号消费者"); p1.start(); p2.start(); c1.start(); } }