package 线程;
/**
* 生产者和消费者的问题 两种情况 一个生产者和一个消费者 多个生产者和多个消费者
*
* 代码描述 一个 egg 类表示生产者 和消费者 生产或消费的 蛋 一个 eggbox 类表示 装蛋 的容器 有固定大小 一个生产者类 一个消费者类
* 生产者不停的生产蛋, eggbox 满了就停止生产 消费者不停的消费但, eggbox 空调就停止消费
*/
public class ProducerAndConsumer {
public static void main(String[] args) {
EggBox eb = new EggBox(9);
Producers p = new Producers(eb);
Producers p1 = new Producers(eb);
Consumers c = new Consumers(eb);
Consumers c1 = new Consumers(eb);
new Thread(p).start();
new Thread(p1).start();
new Thread(c).start();
new Thread(c1).start();
}
}
class Egg {
public int id;
public Egg(int id) {
this.id = id;
}
}
class EggBox {
// 表示能放多少个蛋
public EggBox(int size) {
eggs = new Egg[size];
}
int num = 0; // 数组的索引
private Egg[] eggs;
public int getSize() {
return eggs.length;
}
public synchronized void push(Egg g) {
// 如果蛋的数量满了 就让生产的线程进入等待状态
while (num >= eggs.length) { // 多个生产者时必须用while,不然 可能几个生产者等在下边,造成数据错乱
try {
this.wait();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
eggs[num++] = g;
System.out.println("the producer make egg --total--" + num);
this.notifyAll(); // 多个生产者线程时用 notifyAll() 单个生产者线程时用 notify()
}
public synchronized Egg pop() {
// //如果蛋的数量没了 就让生产的线程进入等待状态
while (num <= 0) { // 多个消费者时必须用while,不然 可能几个消费者等在下边,造成数据错乱
try {
this.wait();
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Egg egg = eggs[--num];
System.out.println("the consumer eat the egg-------total---" + num);
this.notifyAll(); // 多个消费者线程时用 notifyAll() 单个消费者线程时用 notify()
return egg;
}
}
class Producers implements Runnable {
private EggBox eb;
public Producers(EggBox eb) {
this.eb = eb;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
eb.push(new Egg(i));
try {
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumers implements Runnable {
private EggBox eb;
public Consumers(EggBox eb) {
this.eb = eb;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
Egg egg = eb.pop();
try {
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
相关文章
- Java多线程---生产者消费者练习题
- 记录工作中遇到的BUG,经典的数据库时区问题和字段类型tinyint(1)问题
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
- 母鸡下蛋实例:多线程通信生产者和消费者wait/notify和condition/await/signal条件队列
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
- Java多线程系列--“基础篇”11之 生产消费者问题
- 关于js中的单线程和异步事件同操作系统的生产者消费者模型的理解
- 关于CoreData和SQLite多线程访问时的线程安全问题
- 玩转经典算法之字符串匹配(一) 问题引入和朴素的匹配算法
- Android 主线程和子线程通信问题