• 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,不知道用图中的关系合适不合适,如若有不恰当的地方,还请大神指点一二。

     

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

  • 相关阅读:
    [转]GPS原始数据说明
    [转]标准USB,MiniUSB接口定义
    warning C4819: 该文件包含不能在当前代码页(936)中表示的字符
    with用法
    turn out用法
    keep用法
    Stop doing和Stop to do和Stop...from doing有什么不同
    figure用法
    wanna用法
    seem用法
  • 原文地址:https://www.cnblogs.com/zhoulitong/p/6412365.html
Copyright © 2020-2023  润新知