• 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 }
  • 相关阅读:
    阿里Canal中间件的初步搭建和使用
    深入理解Java String类
    深入理解Java中的String
    Docker 容器数据卷(挂载)
    在docker容器下利用数据卷实现在删除了mysql容器或者镜像的情况下恢复数据
    EFK(Elasticsearch+Filebeat+Kibana)收集容器日志
    Docker 容器日志占用空间过大解决办法
    四种软件架构,看看你属于哪个层次
    Kubernetes 如何只授予某一 Namespace 的访问权限
    Docker实验Docker的网络配置
  • 原文地址:https://www.cnblogs.com/zhangqiling/p/11323255.html
Copyright © 2020-2023  润新知