Java—多线程实现PV效果

前言

    还记得今年参加自学操作系统考试,最难分析的就是PV这部分,然而伟大的米老师却用一个放东西吃东西的小例子,把PV讲的栩栩如生,言简意赅。学J2SE时学到了线程部分,里面提到了线程同步,死锁问题等等一系列问题,现在(结合马士兵老师分析例子,通过java语言实现当时的PV效果。

内容

  • 需求:

    生产者生产窝头给消费者吃,生产者将生产的窝头放到篮子里,消费者拿着吃。为了防止生产者生产的窝头放满了篮子,再生产放不了或者消费者一直吃窝头,最后篮子的窝头没了消费者饿死了,这种情况。需要引入多线程,在生产者和消费者同时进行。其中生产者如果把篮子填满了,这时需要停下来,通知消费者赶紧吃,反之,消费者吃了窝头,吃完了后也已应该停下来,赶紧通知生产者生产窝头。

  • 根据马士兵老师的面向对象分析方法来分析:

    对象:生产者、消费者、篮子、窝头

  • 技术点:

    线程创建启动;类实现接口进而实现接口方法;异常的处理;notify()方法应用;数组和其他一些循环结构等的应用;

  • UML


  • Demo

/*
	作者:周丽同
	说明:生产者生产窝头给消费者吃,引用多线程保证这个流程正常运行;
*/
public class ProducerConsumer{
	public static void main(String[] args){
		SyncStack ss = new SyncStack();
		new Thread(new Producer(ss)).start();//创建线程,并启动线程;
		new Thread(new Consumer(ss)).start();//创建线程,并启动线程;
	}
}

//窝头类
class WoTou{
	int id;
	WoTou(int id){
		this.id=id;
	}
	
	public String toString(){
		return "窝头" + id;
	}
}

//生产池
class SyncStack{
	int index = 0;//标记现在有几个窝头;
	WoTou[] arrayWoTou = new WoTou[6];
	
	//生产者向生产池中放入窝头;
	public synchronized void push(WoTou wt){ //"synchronized"用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码
		//要用while不要用if,如果用if出现例外的话,会继续向下进行,导致索引溢出;
		while(index >= 6){
			try{
				this.wait();
			}catch(InterruptedException e){
				e.printStackTrace();//用来跟踪异常事件的发生时执行堆栈的内容;
			}
		}
		
		notify();//随机通知一个正在等待的线程;
		arrayWoTou[index] = wt;
		index++;
	}
	
	//消费者从生产池中消费窝头;
	public synchronized WoTou pop(){
		while(index <= 0){
			try{
				this.wait();
			}catch(InterruptedException e){
				e.printStackTrace();//用来跟踪异常事件的发生时执行堆栈的内容;
			}
		}
		
		notify();//随机通知一个正在等待的线程;
		//先要index--因为index记录的是当前的窝头个数;
		index--;
		return arrayWoTou[index];
	}
}

//生产者
class Producer implements Runnable{
	SyncStack ss = new SyncStack();
	Producer(SyncStack ss){
		this.ss=ss;
	}
	
	public void run(){
		for(int i=1;i<=10;i++){
			WoTou wt = new WoTou(i);
			ss.push(wt);
			System.out.printIn("生产了:" + wt);
		}
	}
}

//消费者
class Consumer implements Runnable{
	SyncStack ss = new SyncStack();
	Consumer(SyncStack ss){
		this.ss=ss;
	}
	
	public void run(){
		for(int i=1;i<=10;i++){
			WoTou wt = null;
			wt = ss.pop();
			System.out.printIn("消费了" + wt);
		}
	}
}

小结

    根据需求,自己尝试画了UML,不知道用图中的关系合适不合适,如若有不恰当的地方,还请大神指点一二。

 

感谢您的宝贵时间······

posted @ 2016-07-13 17:23  小小小同  阅读(319)  评论(0编辑  收藏  举报