zoukankan      html  css  js  c++  java
  • Java多线程生产者消费者模式(一)之两个线程交替执行

    生产者与消费者模式能够实现两个线程交替执行,进一步深入之后能够实现让线程A->B->C->A这个多个线程互相唤醒,形成一个圈。

    本篇,我们模拟一个包子铺,厨师线程作为生产者;吃货线程作为消费者。

    生产者消费者模式的基本套路

    1.生产者与消费判断是否等待的判断条件是相反的
    2.生产者线程处理完后,唤醒消费者线程
    3.消费者线程处理完后,唤醒生产者线程

    生产者消费者模式伪代码

    ThreadA(){
     while(判断条件){
     //生产者与消费的判断条件是相反的
     this.wait();
     }
     //语句块-->会改变判断条件
     this.notifyall();
    }
    
    
    ThreadB(){
     while(判断条件){
     //生产者与消费的判断条件是相反的
     this.wait();
     }
     //语句块-->会改变判断条件
     this.notifyall();
    }

    模拟包子铺,厨师线程为生产者;吃货线程为消费者。

    public class Bun {
        public static void main(String[] args) {
            SteamedBun bun = new SteamedBun();
            new Thread(() -> {
                for (int i = 0; i < 5; i++) {
                    try {
                        bun.produce();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }, "厨师").start();//定义了一个厨师线程,生长包子
            new Thread(() -> {
    
                for (int i = 0; i < 5; i++) {
                    try {
                        bun.eat();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "吃货").start();//定义了一个吃货线程,吃包子
        }
    }
    
    
    class SteamedBun {
        private int num = 0;//包子数量
    
        //生产者,包子铺的厨师
        public synchronized void produce() throws InterruptedException {
            if (num != 0) {
                //如果包子数量不等0就等着,厨师不用生产包子
                this.wait();
            }
            num++;
            System.out.println(Thread.currentThread().getName() + "---生产了" + num + "包子---,剩余包子数:" + num);
            this.notifyAll();//厨师做好了包子,叫吃货去吃
        }
    
        //消费者-->吃包子的吃货
        public synchronized void eat() throws InterruptedException {
            if (num == 0) {
                //如果包子数量等于0吃货就等着厨师做包子,
                this.wait();
            }
    
            System.out.println(Thread.currentThread().getName() + "---吃了" + num + "包子---,剩余包子数:" + (--num));
            System.out.println("吃货叫厨师去做包子");
            this.notifyAll();//吃货发现没有包子了,叫厨师去做包子
        }
    }

    以上,因为只有两个线程,所以每次唤醒的都是对方。

    当出现多个线程时,就会把出自己外所有线程都唤醒,就会出现问题。

  • 相关阅读:
    从hadoop框架与MapReduce模式中谈海量数据处理
    Hadoop
    Clone Graph
    Gas Station
    ZigZag Conversion
    String to Integer (atoi)
    Palindrome Number
    Container With Most Water
    Longest Common Prefix
    求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)
  • 原文地址:https://www.cnblogs.com/majestyking/p/12445828.html
Copyright © 2011-2022 走看看