Java实现生产与消费(完美注释版)

  1 /**
  2  * 2019年8月8日17:42:23
  3  * 目的:Java多线程实现生产与消费
  4  * @author 张涛
  5  *
  6  *    多态:
  7  *        一个父类的引用既可以指向父类对象
  8  *        也可以指向子类对象
  9  *        它会根据当前时刻指向的不同
 10  *        自动调用该对象里面的属性和方法
 11  *
 12  *    this:
 13  *        this在构造方法中表示正在构造的对象
 14  *        this在一般方法中表示正在调用的对象
 15  */
 16 
 17 //构建栈(杯子)类
 18 class synstack
 19 {
 20     //数组相当于货架,每次只能放入6个
 21     char[] data = new char[6];
 22     
 23     //数组当前有效元素个数
 24     int cnt = 0;
 25     
 26     //生产方法
 27     public synchronized void push(char ch)
 28     {
 29         //每一次都要判断货架是否满了,如果满了,就wait,唤醒另一个进程
 30         while(cnt == data.length)
 31         {
 32             //异常处理,wait属于必须要捕获的异常
 33             try
 34             {
 35                 this.wait();
 36             }
 37             catch(Exception e)
 38             {
 39                 //可以不做任何处理
 40             }
 41         }
 42         //唤醒另一个进程
 43         this.notify();
 44         
 45         //讲数据以压栈的方式存入货架
 46         data[cnt] = ch;
 47         
 48         //有效个数自增
 49         cnt++;
 50         
 51         System.out.printf("第%d个产品已经生产好,该产品为%c
",cnt,ch);
 52     }
 53     
 54     //消费方法
 55     public synchronized char pop()
 56     {
 57         //定义货物
 58         char ch = 0;
 59         
 60         //每一次都要检查是否已经把杯子里的货物消费完
 61         //如果消费完了,则进入等待状态,唤醒另一个进程
 62         while(cnt == 0)
 63         {
 64             //wait属于必须要捕获的异常
 65             try
 66             {
 67                 this.wait();
 68             }
 69             catch(Exception e)
 70             {
 71                 //可以不做任何处理
 72             }
 73         }
 74         
 75         //唤醒另一个进程
 76         this.notify();
 77         
 78         //把货物消费掉
 79         cnt--;
 80         ch = data[cnt];
 81         System.out.printf("正在消费掉第%d个货物,该货物为%c
",cnt+1,ch);
 82         return ch;
 83     }
 84 }
 85 
 86 //生产类
 87 class producer implements Runnable
 88 {
 89     //定义父类的引用,私有的原因是不想任意修改父类引用的指向
 90     public synstack ss = null;
 91     
 92     //构造方法,通过多态实现指向的不同,从而达到调用内部方法的作用
 93     public producer(synstack ss)
 94     {
 95         this.ss = ss;
 96     }
 97     
 98     //重写run方法,以用来实现输入
 99     public void run()
100     {
101         char ch = 0;
102         for(int i=0; i<26; i++)
103         {
104             ch =(char) ('a' + i);
105             ss.push(ch);
106             /*
107              * 我当时代码写到这一步遇到的问题
108              * 目前问题是无法调用push方法,只能通过多态的方式解决
109             */
110             
111         }
112     }
113 }
114 
115 //消费类
116 class consumer implements Runnable
117 {
118     //定义父类的引用,私有的原因是不想任意修改父类引用的指向
119     private synstack ss = null;
120     
121     //构造方法,通过多态的实现父类引用指向的不同,从而达到调用内部方法的作用
122     public consumer(synstack ss)
123     {
124         //this出现在构造方法中时表示正在构造的对象
125         this.ss = ss;  
126     }
127     //重写run方法,实现输出
128     public void run()
129     {
130         //刻意得减慢消费的速度
131         for(int i=0; i<26; i++)
132         {
133             //sleep属于必须要捕获的异常
134             try
135             {
136                 Thread.sleep(1000);
137             }
138             catch(Exception e)
139             {
140                 
141             }
142             
143             //开始调用消费
144             ss.pop();
145         }
146         
147         
148     }
149 }
150 
151 
152 public class Pc
153 {
154     public static void main(String[] args)
155     {
156         //构造出杯子对象
157         synstack ss = new synstack();
158         
159         //构建出生产对象
160         producer p = new producer(ss);
161         
162         //构建出消费对象
163         consumer c = new consumer(ss); 
164         
165         //创建线程,第二种方式
166         Thread t1 = new Thread (p);
167         Thread t2 = new Thread (c);
168         
169         //开启线程
170         t1.start();
171         t2.start();
172         
173     }
174 }
原文地址:https://www.cnblogs.com/zhangqiling/p/11323255.html