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();

	}

}

运行结果:




全部评论

相关推荐

请看图片
投递叮咚买菜等公司10个岗位 >
点赞 评论 收藏
分享
我也曾抱有希望:说的好直白
点赞 评论 收藏
分享
牛客737698141号:他们可以看到在线简历的。。。估计不合适直接就拒了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务