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();
}
}