餐厅类:
package lession0718B;
public class Restaurant {
public static int COUNT = 0;// 包子
public static byte[] LOCK = new byte[0];// 锁
}
厨师类:
package lession0718B;
public class Chef implements Runnable {
private String id;
public Chef(String id) {
super();
this.id = id;
}
@Override
public void run() {
while (true) {
synchronized (Restaurant.LOCK) {
if (Restaurant.COUNT >= 50) {
System.out.println("今天任务已结束,共包了" + Restaurant.COUNT + "个包子");
break;
}
Restaurant.COUNT++;
System.out.println("厨师" + id + "包第" + Restaurant.COUNT + "个包子");
}
Thread.yield();// 当前进程建议分配时间片到其它线程
}
}
}
学生类:
package lession0718B;
public class Student implements Runnable {
private String id;
public Student(String id) {
super();
this.id = id;
}
@Override
public void run() {
while (true) {
synchronized (Restaurant.LOCK) {
if (Restaurant.COUNT <= 0) {
System.out.println("包子已经没了");
break;
}
System.out.println("学生" + id + "吃了第" + Restaurant.COUNT + "个包子");
Restaurant.COUNT--;
}
}
Thread.yield();// 当前线程建议分配时间片到其它线程
}
}
主类:
package lession0718B;
public class Test1 {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
Chef c = new Chef(i + "");
Thread t = new Thread(c);
t.start();
}
for (int i = 0; i < 10; i++) {
Student s = new Student(i + "");
Thread t = new Thread(s);
t.start();
}
}
}
输出结果:
第二种方法:
包子类:
package lession0718A;
/**
* 包子类
* @author 123
*
*/
public class Bao {
private String name;
public Bao(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
厨师类:
package lession0718A;
import java.util.ArrayList;
/**
* 厨师类
*
* @author 123
*
*/
public class Chef implements Runnable {
// 定义包子集合
ArrayList<Bao> baoZi;
public Chef(ArrayList<Bao> baoZi) {// 将包子集合作为构造方法的形参
this.baoZi = baoZi;
}
@Override
public void run() {
int number = 0;
while (true) {// 模拟不停的造包子
// synchronized : 因为两个线程共享该集合对象,让两个线程抢锁的目的是保证线程安全
synchronized (baoZi) {// 同步代码块,所对象为包子集合
if (baoZi.size() > 3) {// 至少有4包子才停止生产
try {
baoZi.wait();// 无限等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 程序能执行到这里 说明集合里包子为空
// 向集合中添加元素
Bao bao = new Bao("包子");
baoZi.add(bao);
System.out.println( Thread.currentThread().getName() + "厨师生产了:" + bao.getName());
try {
Thread.sleep(500);// 模拟造包子时间
} catch (InterruptedException e) {
e.printStackTrace();
}
baoZi.notifyAll();// 生产完毕后 唤醒顾客进行消费
}
number++;
if (number == 20) {
return;// 做20个包子就结束
}
}
}
}
顾客类:
package lession0718A;
import java.util.ArrayList;
public class Customer implements Runnable {
// 定义变量:包子集合
ArrayList<Bao> baoZi;
public Customer(ArrayList<Bao> baoZi) {// 将包子集合作为构造方法的形参
this.baoZi = baoZi;
}
@Override
public void run() {
int number = 0;
while (true) {// 模拟不停的吃包子
synchronized (baoZi) {// 同步代码块,所对象为包子集合
if (baoZi.size() == 0) {// 没有包子
try {
baoZi.wait();// 无限等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 需要进行消费,吃包子
Bao bao = baoZi.remove(0);
System.out.println(Thread.currentThread().getName() + "顾客吃了: " + bao.getName());
try {
Thread.sleep(500);// 模拟吃包子时间
} catch (InterruptedException e) {
e.printStackTrace();
}
baoZi.notifyAll();//消费后唤醒生产线程 开始生产包子
}
number++;
if (number == 20) {
return;// 吃20个包子就结束
}
}
}
}
主类:
package lession0718A;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
// 在线程中模拟吃包子和厨师做包子
// 定义包子集合
ArrayList<Bao> baOZi = new ArrayList<>();
// 创建两个线程
Thread t1 = new Thread(new Chef(baOZi));
Thread t2 = new Thread(new Customer(baOZi));
// 设置name
t1.setName("1--");
t2.setName("2--");
// 开启线程
t1.start();
t2.start();
}
}
输出结果: