模拟包子店卖包子的情况
(1)一个厨师包一个包子,一个营业员卖一个包子,包一个包子,卖一个包子
厨师是一个线程,他的任务是包包子,营业员是一个线程,他的的任务是卖包子,他俩之间的联系就是放包子的篮子对象。
package com.part01;
/**
* 用于放包子的篮子
* java中的每个对象,都有一个线程等待队列 这个对象是由线程共享的
* 我是线程,我调baobox这个对象上的cook方法,方法上有个wait,那意思我在哪里等待呢,我是个线程,我就在baobox这个等待队列上等待
* 如果三个线程都调用这个方法,那么等待队列里面就有三个线程睡眠,等待的话,这三个线程都变成阻塞状态
*/
public class BaoBox //用于放包子的篮子
{
private int count=0;//包子的数量默认为0,没有包子
//方法内使用 wait和notify时方法一定声明为synchronized
//厨师生产好以后放包子
public synchronized void cook()//给它同步
{
//放包子有两种状态(1)如果篮子内只能放一个包子,比如是超大包子,那么厨师就歇着了
if(count==1)
{
try {
this.wait();//对于厨师来说,有包子就等待,等待会让线程阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
}else
{
count++;//对于厨师来说,有包子就等待,否则包包子
System.out.println(Thread.currentThread().getName()+"-----包了一个包子。。"+count);
//包好包子之后,唤醒营业员线程去卖包子
this.notify();//唤醒我这个等待队列上的某一个线程,notify all是唤醒所有线程
}
}
//营业员卖包子
public synchronized void sale()
{
if(count==0)
{
try {
this.wait();//没有包子 睡觉
} catch (InterruptedException e) {
e.printStackTrace();
}
}else
{
count--;//有的话就卖。
System.out.println(Thread.currentThread().getName()+"卖出了一个包子.."+count);
//营业员卖完之后,唤醒厨师包包子
this.notify();
}
}
}
package com.part01;
//厨师是个线程
public class Cooker extends Thread
{
//厨师需要一个baobox
BaoBox bb;
public Cooker(String name,BaoBox bb)
{
super(name);
this.bb=bb;
}
@Override
public void run() {
for(int i=0;i<100;i++)
{
bb.cook();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.part01;
public class Saler extends Thread
{
BaoBox bb;
public Saler(String name,BaoBox bb)
{
super(name);
this.bb=bb;
}
@Override
public void run() {
for(int i=0;i<100;i++)
{
bb.sale();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.part01;
public class Main {
public static void main(String[] args)
{
//通过共享等待对象的等待队列,等待,唤醒,等待,唤醒。。。
BaoBox bb = new BaoBox();
Cooker co = new Cooker("老王", bb);
Saler sa = new Saler("小李", bb);
co.start();
sa.start();
}
}
运行结果
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
小李卖出了一个包子..0
老王-----包了一个包子。。1
(2)厨师不断地包包子,营业员不断地卖包子,而且是两个营业员
package com.part01;
public class BaoBox
{
private int count=0;
public synchronized void cook()
{
if(count>=20)//厨师包了20个就可以休息了
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else
{
count++;
System.out.println(Thread.currentThread().getName()+"-----包了一个包子。。"+count);
this.notify();
}
}
public synchronized void sale()
{
if(count<5)//营业员卖的剩下小于5个就可以休息了
{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else
{
count--;
System.out.println(Thread.currentThread().getName()+"卖出了一个包子.."+count);
this.notify();
}
}
}
cooker和saler线程不做改动
package com.part01;
public class Main {
public static void main(String[] args) {
BaoBox bb=new BaoBox();
Cooker co=new Cooker("老王",bb);
Saler sa=new Saler("小李",bb);
Saler sa1=new Saler("lisa",bb);
co.start();
sa.start();
sa1.start();
}
}
运行结果如下:
老王-----包了一个包子。。1
老王-----包了一个包子。。2
老王-----包了一个包子。。3
老王-----包了一个包子。。4
老王-----包了一个包子。。5
老王-----包了一个包子。。6
lisa卖出了一个包子..5
老王-----包了一个包子。。6
小李卖出了一个包子..5
lisa卖出了一个包子..4
老王-----包了一个包子。。5
老王-----包了一个包子。。6
lisa卖出了一个包子..5
小李卖出了一个包子..4
(3)三个厨师包不同的包子,