管程法(利用缓冲区解决)
管程法适用于生产与消费同时进行的模式
//测试:生产者消费者模型---管程法(利用缓冲区解决)
//wait() notifyAll()
//生产者 消费者 产品 缓冲区
public class Test01 {
public static void main(String[] args) {
SynContainer container = new SynContainer();
Provider provider = new Provider(container);
Consumer consumer = new Consumer(container);
new Thread(provider, "生产者01").start();
new Thread(provider, "生产者02").start();
new Thread(provider, "生产者03").start();
new Thread(consumer, "消费者01").start();
new Thread(consumer, "消费者02").start();
}
}
//容器
class SynContainer {
//容器大小
int size = 100;
//容器计数器
int count = 0;
//生产者放入产品
public synchronized void push() throws InterruptedException {
//如果容器满了 则等待消费者消费
while (count >= size){ //注:此处若是多线程 while判断无法替换为if
//若是if判断 醒来后直接向下执行 不会判断此时容器是否由其他生产者线程填满 进而导致越界
//而while循环在醒来后会重新执行一次while 若出现上述情况则让线程重新沉睡
//通知消费者消费 生产者等待
this.wait();
}
//已生产 通知消费者消费(唤醒沉睡的消费者线程)
this.notifyAll();
//生产
count += 1;
}
//消费者消费产品
public synchronized void pop() throws InterruptedException {
while (count <= 0){
//等待生产者生产 消费者等待
this.wait();
}
//已消费 通知生产者生产(唤醒沉睡的生产者线程)
this.notifyAll();
//消费
count -= 1;
}
}
//生产者
class Provider implements Runnable{
SynContainer container;
public Provider(SynContainer container) {
this.container = container;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(10);
container.push();
System.out.println("生产了编号为" + container.count + "的产品");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//消费者
class Consumer implements Runnable{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(10);
container.pop();
System.out.println("消费了编号为" + container.count + "的产品");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
信号灯法
信号灯法适用于生产和消费不同时进行的模式
//测试:生产者消费者模型---信号灯法(标识位)
public class Test02 {
public static void main(String[] args) {
Restaurant restaurant = new Restaurant();
Cook cook = new Cook(restaurant);
Diner diner = new Diner(restaurant);
new Thread(cook, "厨师").start();
new Thread(diner, "食客").start();
}
}
class Cook implements Runnable {
Restaurant restaurant;
public Cook(Restaurant restaurant) {
this.restaurant = restaurant;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
restaurant.cooking();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Diner implements Runnable{
Restaurant restaurant;
public Diner(Restaurant restaurant) {
this.restaurant = restaurant;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(500);
restaurant.eating();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Restaurant{
boolean isCooking = true;
int count = 1;
public synchronized void eating() throws InterruptedException {
while (isCooking) {
this.wait();
}
System.out.println("已食用第" + count + "号菜品");
isCooking = !isCooking;
count++;
notifyAll();
}
public synchronized void cooking() throws InterruptedException {
while (!isCooking){
this.wait();
}
System.out.println("已制作第" + count + "号菜品");
isCooking = !isCooking;
notifyAll();
}
}