一、题目分析
有一个吃货能吃10碗面条,厨师可以做面条 ,还有一张桌子控制生产者和消费者,当桌子上有面条时,吃货会开吃,厨师会等待 ,当桌子没面条时,吃货会等待 并唤醒厨师做饭
多线程4步套路
/*
多线程4步套路
1. 循环
2.同步代码块
3.判断共享数据是否到了末尾(到了末尾) 建议先写到了末尾的情况 因为到了末尾的情况更简单
4.判断共享数据是否到了末尾(没到末尾,执行题目的核心逻辑)
*/
二、完整代码
Foodie类
package huang3;
// 消费者
public class Foodie extends Thread {
@Override
public void run() {
/*
多线程4步套路
1. 循环
2.同步代码块
3.判断共享数据是否到了末尾(到了末尾) 建议先写到了末尾的情况 因为到了末尾的情况更简单
4.判断共享数据是否到了末尾(没到末尾,执行题目的核心逻辑)
*/
while (true) {
synchronized (Desk.lock) {
if (Desk.count == 0) {//吃货把10碗面条全部吃完了就到了末尾
break;
} else {
//先去判断桌子上是否有面条
if (Desk.state == 0) {//表示没有
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {//表示有面条
Desk.count--;//每次进入循环后 最大吃饱数-1
System.out.println("吃货正在吃面条 ,还能吃" + Desk.count + "碗");
//吃完之后唤醒厨师接着做
Desk.lock.notifyAll();
//最后修改桌子的状态
Desk.state = 0;
}
// 如果有就开吃 没有就等待 吃完之后唤醒厨师接着做 然后把吃的总数-1 最后修改桌子状态
}
}
}
}
}
2.Cook类
package huang3;
// 生产者
public class Cook extends Thread {
@Override
public void run() {
/*
多线程4步套路
1. 循环
2.同步代码块
3.判断共享数据是否到了末尾(到了末尾) 建议先写到了末尾的情况 因为到了末尾的情况更简单
4.判断共享数据是否到了末尾(没到末尾,执行题目的核心逻辑)
*/
while (true) {
synchronized (Desk.lock) {
if (Desk.count == 0) {//表示吃货已经吃不下了
break;
} else {//表示吃货还能吃
if (Desk.state == 1) {//表示桌子上有事物
try {
Desk.lock.wait();
} catch (Exception e) {
}
} else {//表示没有食物 要做面条
System.out.println(getName() + "做了一碗面条");
//修改桌子的状态
Desk.state = 1;
// 叫醒等待的消费者开吃
Desk.lock.notifyAll();
}
}
}
}
}
}
3.Desk类
package huang3;
// 控制生产者和消费这的第三者
public class Desk {
//这个变量表示桌子上是否有面条 0:没有 1 有面条
public static int state = 0;
//总个数 表示吃货最多只能吃10碗面条
public static int count = 10;
//锁对象
public static Object lock = new Object();
}
三、运行结果