利用同步代码块修饰
public class Desk {
private Integer count = 0; //定义线程是第几次运行
private Boolean flag = false;//设置线程的一个状态 用来判断该调用哪个线程了
//因为该方法用了synchronized修饰 所以不会出现线程安全问题 又叫同步方法
public synchronized void makeFood() {
// wait notifyAll 必须在同步代码块中synchronized
try {
while (flag) { //如果状态为ture 说明现在有餐桌上面有东西 厨子这个线程应该去等待
this.wait();
}
//如果flag为false 说明现在餐桌上没食物 厨子该去做食物
count++;
System.out.println(Thread.currentThread().getName() + "做了第" + count + "个包子");
//厨子做好了 用一个状态标记下已经做好了 方面吃货能做出判断 知道东西做好了 可以吃了
flag = true;
//告诉吃货 现在能吃了 唤醒他
this.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void eatFood() {
try {
while (!flag) { //判断食物的状态 如果为false 说明餐桌上没食物 让吃货先等一下
this.wait();
}
//如果flag为true 说明有食物 吃货可以去吃了
System.out.println(Thread.currentThread().getName() + "做了第" + count + "个包子");
flag = false;//吃完东西了 把食物的状态改变一下 说明已经吃完了 然后去叫厨子让做菜
this.notifyAll(); //唤醒厨子 该做饭了 东西吃完了
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
生产者类
public class ProducerRun implements Runnable {
private Desk desk ;
public ProducerRun(Desk desk) {
this.desk = desk;
}
@Override
public void run() {
while (true) {
desk.makeFood();
}
}
}
消费者类
public class ConsumerRun implements Runnable{
private Desk desk;
public ConsumerRun(Desk desk) {
this.desk = desk;
}
@Override
public void run() {
//以为要执行多次 所以用了死循环
while (true){
desk.eatFood();
}
}
}
利用Lock锁和Condition解决(方法二)
public class Desk {
private Integer count=0;
private Boolean flag=false;
private final Lock LOCK =new ReentrantLock();
private final Condition PRODUCER_CONDITION=LOCK.newCondition();
private final Condition CONSUMER_CONDITION=LOCK.newCondition();
//生产者 用lock锁 必须用try catch finall 不然中途出现异常程序会停止
public void makeFood(){
try {
LOCK.lock();
while (flag){ //如果状态为ture 说明现在有餐桌上面有东西 厨子这个线程应该去等待
PRODUCER_CONDITION.await();
}
count++; // 说明现在餐桌上没食物 厨子该去做食物
System.out.println(Thread.currentThread().getName()+"做了第"+count+"个包子");
flag=true; //厨子做好了 用一个状态标记下已经做好了 方面吃货能做出判断 知道东西做好了 可以吃了
CONSUMER_CONDITION.signal(); //唤醒吃货 能吃了
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
LOCK.unlock();
}
}
public void eatFood(){
try {
LOCK.lock();
while (!flag){ //判断食物的状态 如果为false 说明餐桌上没食物 让吃货先等一下
CONSUMER_CONDITION.await();
}
//如果flag为true 说明有食物 吃货可以去吃了
System.out.println(Thread.currentThread().getName()+"做了第"+count+"个包子");
flag=false; //吃完东西了 把食物的状态改变一下 说明已经吃完了 然后去叫厨子让做菜
PRODUCER_CONDITION.signal();//唤醒厨子 该做饭了 现在
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
LOCK.unlock();
}
}
}
//生成者类
public class PruducerRun implements Runnable{
private Desk desk;
public PruducerRun(Desk desk) {
this.desk = desk;
}
@Override
public void run() {
while (true){
desk.makeFood();
}
}
}
//消费者类
public class ConsumerRun implements Runnable{
private Desk desk;
public ConsumerRun(Desk desk) {
this.desk = desk;
}
@Override
public void run() {
while (true){
desk.eatFood();
}
}
}
测试类 共有的
public class Test {
public static void main(String[] args) {
Desk desk=new Desk();
ConsumerRun consumerRun=new ConsumerRun(desk);
PruducerRun producerRun=new PruducerRun(desk);
Thread t1 =new Thread(consumerRun,"吃货");
Thread t2 =new Thread(consumerRun,"吃货");
Thread t3 =new Thread(consumerRun,"吃货");
Thread t4 =new Thread(producerRun,"厨子");
Thread t5 =new Thread(producerRun,"厨子");
Thread t6 =new Thread(producerRun,"厨子");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
}