线程:生产者消费者模式(管程法)

 1 /**
 2  * 线程生产者消费者模式(管程法)
 3  * 个人理解:所谓管程法,就是将“创造”与“使用”进行解耦,中间加一个缓冲区。
 4  * 就像是服装厂和顾客之间有一个实体店一样,顾客不直接与服装厂联系,不用管是哪个服装厂生产的,服装厂也不管是哪个顾客购买的。
 5  * 加入缓冲区后,生产者将数据放入缓冲区,消费者从缓冲区中取数据,
 6  * 缓冲区满了,就让生产者等待,并提醒消费者取。消费者就继续使用,当缓冲区中有数据被取走或取完了,就提醒生产者生产。
 7  * 
 8  * 代码构造:
 9  *     管程法中,有生产者(多线程)、消费者(多线程)、缓冲容器以及数据
10  *     缓冲容器中固定容器容量并提供生产和消费方法,对容量中的数据进行同步
11  *     生产者开始生产,将容器塞满后,进入等待状态,消费者开始取数据,取走或取空后在提醒生产者生产,往复循环。
12  * 
13  * 方法:
14  *     wait();     //由Object提供,使当前线程等待,让出调度,释放锁
15  *     notifyAll();    //由Object提供,唤醒等待中的全部线程
16  */
17 public class GuanCheng {
18     public static void main(String[] args) {
19         Buffer buffer = new Buffer();
20         Product product = new Product(buffer);
21         Consum consum = new Consum(buffer);
22         product.start();
23         consum.start();
24     }
25 }
26 
27 //生产者
28 class Product extends Thread{
29     Buffer buffer;    //生产者使用缓冲区
30     public Product(Buffer buffer) {
31         this.buffer = buffer;
32     }
33     public void run() {
34         //当缓冲区只要有位置,就生产
35         for(int i = 1;i<=100;i++) {
36             System.out.println("开始生产第"+i+"包辣条");
37             buffer.push();
38         }
39     }
40 }
41 
42 //消费者
43 class Consum extends Thread{
44     Buffer buffer;    //消费者使用缓冲区
45     public Consum(Buffer buffer) {
46         this.buffer = buffer;
47     }
48     public void run() {
49         //当缓冲区没有辣条了,就通知生产者生产
50         for(int i = 1;i<=100;i++) {
51             System.out.println("开始消费第"+i+"包辣条");
52             buffer.move(); //取辣条
53         }
54     }
55 }
56 
57 //缓冲区
58 class Buffer{
59     LaTiao[] laTiaoArr = new LaTiao[10]; //缓冲10包辣条
60     private int count = 0;
61     //生产者存辣条
62     public synchronized void push(){
63         //只要缓冲区有位置,就生产
64         if(count == laTiaoArr.length) {    //如果缓冲区满了,就将线程设置为等待状态
65             try {
66                 this.wait();
67             } catch (InterruptedException e) {
68                 e.printStackTrace();
69             }
70         }
71         laTiaoArr[count] = new LaTiao();
72         count ++;
73         this.notifyAll(); //辣条生产出来后,就通知消费者来拿
74     }
75     //消费者取辣条
76     public synchronized LaTiao move() {
77         if(count == 0) {    //如果缓冲区的辣条拿光了,就将线程设置为等待状态
78             try {
79                 this.wait();
80             } catch (InterruptedException e) {
81                 e.printStackTrace();
82             }
83         }
84         count --;
85         LaTiao laTiaos = laTiaoArr[count];
86         this.notifyAll(); //将辣条取出后,就通知生产者生产辣条。
87         return laTiaos;
88     }
89 }
90 //数据(辣条  )
91 class LaTiao{
92 }

 结果:

开始消费第1包辣条
开始生产第1包辣条
开始生产第2包辣条
开始生产第3包辣条
开始生产第4包辣条
开始生产第5包辣条
开始生产第6包辣条
开始生产第7包辣条
开始生产第8包辣条
开始生产第9包辣条
开始生产第10包辣条
开始生产第11包辣条
开始生产第12包辣条
开始消费第2包辣条
开始消费第3包辣条
开始消费第4包辣条
开始消费第5包辣条
开始消费第6包辣条
开始消费第7包辣条
开始消费第8包辣条
开始消费第9包辣条
开始消费第10包辣条
开始消费第11包辣条
开始生产第13包辣条
开始消费第12包辣条
开始消费第13包辣条
开始消费第14包辣条
开始生产第14包辣条
开始生产第15包辣条
开始生产第16包辣条
开始生产第17包辣条
开始生产第18包辣条
开始生产第19包辣条
开始生产第20包辣条
开始生产第21包辣条

posted @ 2020-07-14 16:54  梅竹疯狂打豆豆  阅读(262)  评论(0)    收藏  举报