JAVA同步-生产者与消费者实现 二
生产者消费者模型:
实现手段:LinkedBlockingQueue(阻塞队列)实现; //LinkedBlockingQueue:底层为链表实现的队列位于
java.lang.Object-->java.util.AbstractCollection<E>-->java.util.AbstractQueue<E>--> java.util.concurrent.LinkedBlockingQueue.
问题描述:吃吐司蛋糕,吐司蛋糕状态:1.面包状态。2.抹酱状态。 3.制作完成状态(待吃态)。4.食用(吃货)。
队列使用过程:可以分别生成 1.制作吐司队列 ,2.抹黄油队列 ,3.涂果酱队列 ,4.吃吐司队列。
图示:
吐司类:
class Toast1{
// 吐司的状态
public enum Status{
DRY, BUTTERED, JAMMED;
}
public final int Id;
private Status status=null;
//初始当前的吐司
Toast1(int Id){
this.Id=Id;
this.status=Status.DRY;
}
//得到当前吐司编号
public int getId() {
return Id;
}
//得到当前吐司状态
public Status status(){
return this.status;
}
//通过状态来判断吐司的位于哪个队列:状态的转换;
//第一步转换
public void FirstChange(){
this.status=Status.BUTTERED;
}
//第二步转换
public void SecondChange(){
this.status=Status.JAMMED;
}
@Override
public String toString() {
return "第" + this.Id + "个吐司,状态是:" + this.status;
}
} 队列实现:用LinkedBlockingQueu阻塞队列类,实现Toast1Queue吐司队列类;
//注也可以不用实现此队列,直接放不同的阻塞队列种。但是这样做思路逻辑不清晰;
//简单的覆写,可以让思路逻辑清晰;
class Toast1Queue extends LinkedBlockingQueue<Toast1> {
private static final long serialVersionUID = 1L;
} 制作吐司第一步:做面包
class FirstToast1 implements Runnable {
// 持有吐司第一个状态队列
private Toast1Queue queue1;
// 吐司制作的编号
private int cnt = 0;
FirstToast1(Toast1Queue queue) {
this.queue1 = queue;
}
public void run() {
try {
while (!Thread.interrupted()) {
// 生成面包
Toast1 t = null;
if (++cnt < 11) { // 默认生成面包所以不需要更改状态;
t = new Toast1(cnt);
}
if (t != null) { // 查看状态
System.out.println(t);
// 放入第一个队列中;
this.queue1.add(t);
}
TimeUnit.MILLISECONDS.sleep(1);
}
} catch (InterruptedException e) {
System.out.println("第一步终断线程!");
// e.printStackTrace();
}
}
} 制作吐司第二步:抹酱
class SecondToast1 implements Runnable {
private Toast1Queue queue1, queue2;
// 线程需要: 队列1,拿出面包。队列2,放入涂酱面包;
SecondToast1(Toast1Queue queue1, Toast1Queue queue2) {
this.queue1 = queue1;
this.queue2 = queue2;
}
public void run() {
try {
while (!Thread.interrupted()) {
// 得到状态1
Toast1 t = this.queue1.take();
// 抹黄油
if (t.getstatus() == Toast1.Status.DRY) {
t.FirstChange();
}
if (t != null) { // 查看状态
System.out.println(t);
// 放入队列2
queue2.add(t);
}
TimeUnit.MICROSECONDS.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("第二步终断线程!");
// e.printStackTrace();
}
}
} 制作吐司第三步:加工完成
class ThirdlyToast1 implements Runnable {
private Toast1Queue queue2, queue3;
// 线程需要: 队列2,拿出涂酱面包。队列3,放入待吃面包;
ThirdlyToast1(Toast1Queue queue2, Toast1Queue queue3) {
this.queue2 = queue2;
this.queue3 = queue3;
}
public void run() {
try {
while (!Thread.interrupted()) {
// 得到状态2
Toast1 t = this.queue2.take();
// 加工待食用
if (t.getstatus() == Toast1.Status.BUTTERED) {
t.SecondChange();
;
}
if (t != null) { // 查看状态
System.out.println(t);
// 放入队列3
queue3.add(t);
}
TimeUnit.MICROSECONDS.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("第三步终断线程!");
// e.printStackTrace();
}
}
} 制作吐司完成:食用
class Eat implements Runnable {
private Toast1Queue queue3;
int cont = 0;
// 线程需要: 队列3,拿出待食用。
Eat(Toast1Queue queue3) {
this.queue3 = queue3;
}
public void run() {
try {
while (!Thread.interrupted()) {
// 得到状态3.
Toast1 t = this.queue3.take();
// 判断信息是否正确:吃的对不对
if (t.getstatus() == Toast1.Status.JAMMED
&& t.getId() == (++cont)) {
System.out.println("食用第" + t.getId() + "完成!");
}
// else 保证正常退出;最后(第11个)放的是一个NULL
else {
//
System.exit(1);
}
TimeUnit.MICROSECONDS.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("第四步终断线程!");
// e.printStackTrace();
}
}
} 线程启动:
public class TestToast1 {
public static void main(String[] args) throws InterruptedException {
Toast1Queue queue1 = new Toast1Queue();
Toast1Queue queue2 = new Toast1Queue();
Toast1Queue queue3 = new Toast1Queue();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new FirstToast1(queue1));
exec.execute(new SecondToast1(queue1, queue2));
exec.execute(new ThirdlyToast1(queue2, queue3));
exec.execute(new Eat(queue3));
TimeUnit.SECONDS.sleep(5);
exec.shutdownNow();
}
} 运行结果:

海康威视公司福利 1154人发布