1. 程式人生 > >多執行緒縣互動例項,生產消費

多執行緒縣互動例項,生產消費

生產者消費者問題是一個非常典型性的執行緒互動的問題。

1. 使用來存放資料
1.1 把棧改造為支援執行緒安全
1.2 把棧的邊界操作進行處理,當棧裡的資料是0的時候,訪問pull的執行緒就會等待。 當棧裡的資料時200的時候,訪問push的執行緒就會等待
2. 提供一個生產者(Producer)執行緒類,生產隨機大寫字元壓入到堆疊
3. 提供一個消費者(Consumer)執行緒類,從堆疊中彈出字元並列印到控制檯
4. 提供一個測試類,使兩個生產者和三個消費者執行緒同時執行,結果類似如下 :

練習-生產者消費者問題

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

121

import java.util.*;

 

 

public class Test {

 

    public static void main(String[] args){

        MyStack<Character> stack = new MyStack<>();

 

 

        for (int i = 0; i < 3; ++i) {

            new Thread(new Producer(stack)).start();//引數為一個帶有runnable介面改寫了run方法的物件

        }

 

        for (int i = 0; i < 2; ++i) {

            new Thread(new Consumer(stack)).start();

        }

    }   

}

 

 

 

class MyStack<T> {

    private LinkedList<T> list;

    private int count;

 

    public MyStack() {

        list = new LinkedList<>();

        count = 0;

    }

 

    public synchronized int getSize() {

        return count;

    }

 

    public synchronized void push(T ele) {

 

        while (count >= 200) {

            try {

                this.wait();

            catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

 

        list.offerLast(ele);

        count++;

 

        this.notifyAll();

    }

 

    public synchronized T pull() {

        while (count <= 0) {

            try {

                this.wait();

            catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

 

        T res =  list.pollLast();

        count--;

 

        this.notifyAll();

        return res;

    }

 

    // return null if stack is empty

    public synchronized T peek() {

        return list.peekLast();

    }

}

 

class Producer implements Runnable {

 

    private MyStack<Character> stack;

 

    public Producer(MyStack<Character> stack) {

        this.stack = stack;

    }

 

    @Override

    public void run() {

        while (true) {

            try {

                Thread.sleep(100);

            catch (InterruptedException e) {

                e.printStackTrace();

            }

 

            char c = generateChar();

            stack.push(c);

            System.out.println("Producer pushed: " + c + " " + stack.getSize());

        }

    }

 

    private char generateChar() {

        return (char)(new Random().nextInt(26) + 'a');//隨機生成英文

    }

}

 

class Consumer implements Runnable {

 

    private MyStack<Character> stack;

 

    public Consumer(MyStack<Character> stack) {

        this.stack = stack;

    }

 

    @Override

    public void run() {

        while (true) {

            try {

                Thread.sleep(100);

            catch (InterruptedException e) {

                e.printStackTrace();

            }

             

            System.out.println("Consumer pulled: " + stack.pull()" " + stack.getSize());

        }

    }

}