一、基本信息
1、场景介绍:厨师和吃货的例子,吃货吃桌子上的面条,吃完让厨师做,厨师做完面条放桌子上,让吃货吃,厨师如果发现桌子上有面条,就不做,吃货发现桌子上没有面条就不吃。
2、线程实现基本步骤:
- 循环
- 同步代码块
- 循环退出条件
- 循环没有退出时,业务代码的实现
二、代码实现
桌子类:
public class Desk {
//食物状态
public static int status = 0;
//锁
public static Object lock = new Object();
//面条剩余数量
public static int count = 5;
}
厨师类:
/**
* 厨师做饭线程
*/
public class Cookie extends Thread{
/**
* 多线线程实现的基本步骤:
* 1、循环
* 2、同步代码块
* 3、循环的退出条件
* 4、未退出时的业务代码逻辑
*/
/**
* 厨师的业务逻辑
* 1、判断桌子上有没有面条
* 2、有面条就等待;没有面条就做面条,并且唤醒等待的吃货吃面条
*/
@Override
public void run() {
while (true){
synchronized (Desk.lock){
//判断面条数量
if (Desk.count == 0) {
break;
}
//判断桌子上是否有面条
if (Desk.status == 1){
//有面条时,就等待
//这里需要用锁对象调用等待方法,目的是为了绑定锁和线程
try {
Desk.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//没有面条就要做面条
System.out.println(getName() + "做了一碗面条");
//改状态,表示面条做好了
Desk.status = 1;
//唤醒吃货吃面条
Desk.lock.notifyAll();
}
}
}
}
}
吃货类:
/**
* 吃货
*/
public class Foodie extends Thread {
/**
* 多线线程实现的基本步骤:
* 1、循环
* 2、同步代码块
* 3、循环的退出条件
* 4、未退出时的业务代码逻辑
*/
/**
* 吃货的业务逻辑
* 1、判断桌子上有没有面条
* 2、有面条就吃;没有面条就等待,并且唤醒等待的厨师做面条
*/
@Override
public void run() {
while (true) {
synchronized (Desk.lock) {
//判断面条数量
if (Desk.count == 0) {
break;
} else {
//判断桌子上是否有面条
if (Desk.status == 1) {
Desk.count--;
System.out.println(getName() + "吃了一碗面条");
System.out.println(getName() + "还能吃" + Desk.count + "碗面条");
Desk.status = 0;
Desk.lock.notifyAll();
}else {
try {
Desk.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
测试类:
public class TestCookie {
public static void main(String[] args) {
Cookie cookie = new Cookie();
Foodie foodie = new Foodie();
cookie.setName("厨师");
foodie.setName("吃货");
cookie.start();
foodie.start();
}
}
运行结果: