桌子上有面条-》吃货执行
桌子上没面条-》生产者制造执行
1、消费者等待
消费者先抢到CPU执行权,发现桌子上没有面条,于是变成等待wait状态,并释放CPU执行权,此时的CPU肯定会被厨师抢到,初始开始做面条,当厨师做完后会对吃货进行提示,notify唤醒吃货来吃。
2、生产者等待
厨师先抢到CUP执行权,但是桌子上有面条,就不能再制作面条,只能等待消费者吃完面条才能做,消费者吃完后需要唤醒厨师继续做
代码逻辑:
厨师:
public class Cook extends Thread{
@Override
public void run() {
//1循环
//2同步代码块
//3共享数据是否到末尾,Yes
//4共享数据是否到末尾,No
while (true){
synchronized (Desk.lock){
if (Desk.count==0){
break;//10碗吃完
}else {
//厨师的核心逻辑
//01判断桌子上是否有食物
if (Desk.foodflag==1){
//02有食物就等待
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else {
//03没有
System.out.println(Thread.currentThread().getName()+"制作食物");
//04改变桌子状态
Desk.foodflag=1;
//05唤醒消费者吃
Desk.lock.notifyAll();
}
}
}
}
}
}
吃货:
public class Customer extends Thread{
@Override
public void run() {
while (true){
synchronized (Desk.lock){
if (Desk.count==0){
break;//10碗吃完
}else {
//吃货的核心逻辑
/*
* 1.判断桌子上有无面条
* 2.没有:自己等待,
* 3.有:吃完,并唤醒厨师做面条,count--
* 4.修改桌子状态*/
if (Desk.foodflag==0){//1.判断桌子上有无面条
try {
Desk.lock.wait();//2.没有:自己等待,
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else {//3.有:吃完,并唤醒厨师做面条,count--
Desk.count--;
System.out.println(Thread.currentThread().getName()+"还能再吃"+Desk.count+"碗");
Desk.lock.notifyAll();
//4.修改桌子状态
Desk.foodflag=0;
}
}
}
}
}
}
桌子:
public class Desk {
//通过变量来控制 0:没食物 1:有食物
public static int foodflag=0;
//总个数,最多做十碗
public static int count=10;
//锁对象
public static Object lock=new Object();
}
//测试类
public class Test {
public static void main(String[] args) {
Customer customer = new Customer();
Cook cook = new Cook();
customer.setName("吃货");
cook.setName("厨师");
customer.start();
cook.start();
}
}
3、阻塞队列实现
接口无法new对象,只能通过两个实现类,第一个可以自定义队列长度。
注意:生产者与消费者必须针对同一个阻塞队列,阻塞队列可以创建在测试类中
厨师:
public class Cook extends Thread{
ArrayBlockingQueue<String> queue;
//创建构造函数,创建对象的时候进行赋值,指定同一个阻塞队列
public Cook(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true){
try {
queue.put("面条");
System.out.println("厨师做了一碗面条");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
消费者:
public class Customer extends Thread{
ArrayBlockingQueue<String> queue;
public Customer(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true){
try {
String food=queue.take();//tack底层也进行了加锁,不需要我们自己定义
System.out.println("获取食物"+food);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(1);
Customer customer = new Customer(queue);
Cook cook = new Cook(queue);
customer.setName("吃货");
cook.setName("厨师");
customer.start();
cook.start();
}
}