消费者和生产者模式
用继承Thread方式,用wait和notifyAll方法实现。
消费者和生产者模式的特点
1. 什么时候生产:仓库没有满的时候,生产者这可以生产,消费者也可以消费,仓库满的时候停止生产
2. 什么时候消费: 仓库有货的时候消费,没有货不能消费
3. 通知生产:消费者发现没有货,消费者通知生产者生产
4. 通知消费:生产者生产出产品后,通知消费者消费
代码实现
package com.java.javabase.thread.base;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/*
1. 什么时候生产:仓库没有满的时候,生产者这可以生产,消费者也可以消费,仓库满的时候停止生产
2. 什么时候消费: 仓库有货的时候消费,没有货不能消费
3. 通知生产:消费者发现没有货,消费者通知生产者生产
4. 通知消费:生产者生产出产品后,通知消费者消费
*/
@Data
@Slf4j
@AllArgsConstructor
@RequiredArgsConstructor
class Dept {
private int capacity;
private int size;
/*
@param val 是生产的产品数量
*/
public synchronized void produce(int val) {
//
int remainder = val;
while (remainder > 0) {
if (size >= capacity) {
try {
//仓库满了,等待不在执行生产
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int incre = (size + remainder) > capacity ? capacity - size : remainder;
size += incre;
remainder -= incre;
log.info("produce {} .depet increment {}, remainder {} ,current size is {}",
val,incre, remainder, size);
//结束生产,通知消费或者生产
notifyAll();
}
}
public synchronized void custom(int val) {
int remainder = val;
while(remainder>0){
if(size<=0){
try {
//仓库无货,等待不在消费
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int descre =(size<remainder)?size:remainder;
size -=descre;
remainder -=descre;
log.info("custom {}. depet descrement {}, remainder {} ,current size is {}",
val,descre, remainder, size);
//结束消费,通知消费或者生产
notifyAll();
}
}
}
@AllArgsConstructor
class Producer {
private Dept dept;
public void produce(final int val) {
new Thread() {
@Override
public void run() {
dept.produce(val);
}
}.start();
}
}
@AllArgsConstructor
class Custom {
private Dept dept;
public void custom(final int val) {
new Thread() {
@Override
public void run() {
dept.custom(val);
}
}.start();
}
}
public class DemoProCustomTest {
public static void main(String[] args) {
Dept dept =new Dept(100,0);
Producer producer =new Producer(dept);
Custom custom =new Custom(dept);
producer.produce(100);
producer.produce(190);
custom.custom(150);
custom.custom(80);
}
}
日志结果输出
因为多线程,所以下面的结果只是其中之一的可能性
2019-07-31 19:10:13,297 [Thread-0] INFO Dept - produce 100 .depet increment 100, remainder 0 ,current size is 100
2019-07-31 19:10:13,299 [Thread-3] INFO Dept - custom 80. depet descrement 80, remainder 0 ,current size is 20
2019-07-31 19:10:13,299 [Thread-2] INFO Dept - custom 150. depet descrement 20, remainder 130 ,current size is 0
2019-07-31 19:10:13,300 [Thread-1] INFO Dept - produce 190 .depet increment 100, remainder 90 ,current size is 100
2019-07-31 19:10:13,300 [Thread-2] INFO Dept - custom 150. depet descrement 100, remainder 30 ,current size is 0
2019-07-31 19:10:13,300 [Thread-1] INFO Dept - produce 190 .depet increment 90, remainder 0 ,current size is 90
2019-07-31 19:10:13,300 [Thread-2] INFO Dept - custom 150. depet descrement 30, remainder 0 ,current size is 60