经典生产者消费者问题:
场景:
1.模拟生产者生产电脑放到仓库里面,但是仓库只能存放100台电脑,仓库满了生产者等待消费者消费再生产。
2.消费者从仓库里面取出电脑,但是仓库中没电脑时等待生产者生产再取。
3.模拟3个生产者和3个消费者线程同时运行。
程序结构如下:
1.仓库类
package com.lijie.bean;
/**
* 仓库
* @author lijie
*
*/
public class CangKu {
/**
* 用于保存产品的数组
*/
private NoteBookPC[] nbs = new NoteBookPC[100];
/**
* 当前仓库中产品的数量
*/
private int size = 0;
/**
* 生产了电脑,存到仓库中
* @param nb
*/
public synchronized void add(NoteBookPC nb) {
// 判断是否爆仓,如果爆仓则等待
while(size >= 100) {
try {
this.notifyAll();
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
nbs[size ++] = nb;
}
/**
* 从仓库中取出电脑,卖出去了
* @return
*/
public synchronized NoteBookPC get() {
// 判断是否没有产品,如果没有则
while(size <= 0) {
try {
this.notifyAll();
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
NoteBookPC nb = nbs[size - 1];
nbs[size - 1] = null;
size --;
return nb;
}
}
2.笔记本类
package com.lijie.bean;
/**
* 笔记本
* @author lijie
*
*/
public class NoteBookPC {
/**
* 序列号
*/
private String seriaId;
/**
* 笔记本名称
*/
private String name;
public String getSeriaId() {
return seriaId;
}
public void setSeriaId(String seriaId) {
this.seriaId = seriaId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "NoteBookPC [name=" + name + ", seriaId=" + seriaId + "]";
}
public NoteBookPC(String seriaId, String name) {
super();
this.seriaId = seriaId;
this.name = name;
}
public NoteBookPC() {
super();
}
}
3.消费者类
package com.lijie.bean;
/**
* 消费者线程
* @author lijie
*
*/
public class Consumer implements Runnable {
/**
* 消费者名称
*/
private String name;
/**
* 用于取产品的仓库
*/
private CangKu ck;
/**
* 构造方法
* @param name
* @param ck
*/
public Consumer(String name, CangKu ck) {
super();
this.name = name;
this.ck = ck;
}
/**
* 不停的消费
*/
@Override
public void run() {
int i = 0;
while(true) {
// 从仓库中取出一台电脑
NoteBookPC nb = ck.get();
// 卖出电脑
System.out.println(name + "卖出了第" + (++i) + "台电脑:" + nb);
}
}
}
4.生产者类
package com.lijie.bean;
import java.util.UUID;
/**
* 生产者线程
* @author lijie
*
*/
public class Producer implements Runnable {
/**
* 生产者名称
*/
private String name;
/**
* 生产后保存的仓库
*/
private CangKu ck;
/**
* 构造方法
* @param name
* @param ck
*/
public Producer(String name, CangKu ck) {
super();
this.name = name;
this.ck = ck;
}
/**
* 不停生产
*/
@Override
public void run() {
int i = 0;
while(true) {
// 产生序列号
String sid = UUID.randomUUID().toString();
// 生产笔记本
NoteBookPC nb = new NoteBookPC(sid, name + "生产的第" + (++i) + "台笔记本");
System.out.println(name + "生产了电脑:" + nb);
// 添加到仓库中
ck.add(nb);
}
}
}
5.MainClass
package com.lijie.bean;
public class MainClass {
public static void main(String[] args) {
// 创建仓库
CangKu ck = new CangKu();
// 创建3个生产者
Producer p1 = new Producer("黎杰1", ck);
Producer p2 = new Producer("黎杰2", ck);
Producer p3 = new Producer("黎杰3", ck);
// 创建3个消费者
Consumer c1 = new Consumer("黎杰4", ck);
Consumer c2 = new Consumer("黎杰5", ck);
Consumer c3 = new Consumer("黎杰6", ck);
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
new Thread(c1).start();
new Thread(c2).start();
new Thread(c3).start();
}
}