生产者消费者实战

本篇主要是通过一段JAVA代码来模拟生产者和消费者的工作流程,来介绍生产者消费者这一模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package com.pattern;
 
import java.util.ArrayList;
import java.util.List;
 
public class ProducerConsumerMain {
 
    /**
     * 缓冲区,生产者放入数据,消费者取出数据
     */
    private static class Buffer {
 
        /**
         * 存取数据通过list来实现
         */
        private List<Integer> data = new ArrayList<>();
 
        /**
         * 设置存放最大值,当data大小达到MAX时,不允许再放数据
         */
        private static final int MAX = 2;
 
        /**
         * 设置取数的最小值,当data大小是MIN时,不允许再取数据
         */
        private static final int MIN = 0;
 
        public synchronized int get() {
            while (MIN == data.size()) {
                try {
                    // 相当于this.wait();当前方法处于等待状态,并释放this对象锁,释放this监视器
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Integer i = data.remove(0);
            // 释放this监视器,唤醒等待this监视器的线程,但该方法不会释放this对象锁
            notifyAll();
            return i;
        }
 
        public synchronized void put(int value) {
            while (MAX == data.size()) {
                try {
                    // 相当于this.wait();当前方法处于等待状态,并释放this对象锁,释放this监视器
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            data.add(value);
            // 释放this监视器,唤醒等待this监视器的线程,但该方法不会释放this对象锁
            notifyAll();
        }
    }
 
    private static class Consumer extends Thread {
        private Buffer buffer;
        private int number;
 
        public Consumer(Buffer b, int number) {
            buffer = b;
            this.number = number;
        }
 
        @Override
        public void run() {
            int value;
            for (int i = 0; i < 10; i++) {
                // 从缓冲区中获取数据
                value = buffer.get();
                try {
                    // 模拟消费数据所用时间
                    sleep(1000);
                } catch (InterruptedException e) {
                }
                System.out.println("消费者 #" + this.number + " got: " + value);
            }
        }
    }
 
    private static class Producer extends Thread {
        private Buffer buffer;
        private int number;
 
        public Producer(Buffer b, int number) {
            buffer = b;
            this.number = number;
        }
 
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    // 模拟生产数据所用时间
                    sleep(500);
                } catch (InterruptedException e) {
                }
 
                // 将数据放入缓冲区
                buffer.put(i);
                System.out.println("生产者 #" + this.number + " put: " + i);
            }
        }
    }
 
    /**
     * 模拟生产者消费者行为
     *
     * @param args
     */
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        Producer p1 = new Producer(buffer, 1);
        Consumer c1 = new Consumer(buffer, 1);
        p1.start();
        c1.start();
    }
}

  

posted on   阿泰555  阅读(31)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示