一、基本信息
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、有面条就等待;没有面条就做面条,并且唤醒等待的吃货吃面条*/@Overridepublic 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、有面条就吃;没有面条就等待,并且唤醒等待的厨师做面条*/@Overridepublic 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();}
}
运行结果: