马老师的WoTou生产消费线程讲解例子

public class ProducerConsumer {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        Producer p = new Producer(ss);
        Consumer c = new Consumer(ss);
        new Thread(p).start();
        new Thread(p).start();
        new Thread(p).start();
        new Thread(c).start();
    }
}

//定义一个WoTou类,在类中有id以标记是哪个窝头,重写了toString方法
class WoTou {
    int id;
    WoTou(int id) {
        this.id = id;
    }
    public String toString() {
        return "WoTou : " + id;
    }
}

//定义一个篮子的对象,用于装WoTou,在类中有push方法,用于装WoTou,pop方法,用于吃WoTou
class SyncStack {
    int index = 0;
    WoTou[] arrWT = new WoTou[6];
    /*
    *wate()只有在锁定(synchronized)的时候才能使用
    */
    //push用于装WoTou,当WoTou数达到6时wait()休息
    public synchronized void push(WoTou wt) {
        while(index == arrWT.length) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //唤醒瓦特()
        this.notifyAll();
        arrWT[index] = wt;
        index ++;
    }

    //pop用于吃WoTou,当WoTou数为0时wait()
    public synchronized WoTou pop() {
        while(index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
        index--;
        return arrWT[index];
    }
}

//继承Runnable接口,实现run方法的Producer类,一个对象只生产20个WoTou
class Producer implements Runnable {
    SyncStack ss = null;
    Producer(SyncStack ss) {
        this.ss = ss;
    }

    public void run() {
        for(int i=0; i<20; i++) {
            WoTou wt = new WoTou(i);
            ss.push(wt);
System.out.println("生产了:" + wt);
            try {
                Thread.sleep((int)(Math.random() * 200));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//继承Runnable接口,实现run方法的Consumer类,一个对象只消费20个WoTou
class Consumer implements Runnable {
    SyncStack ss = null;
    Consumer(SyncStack ss) {
        this.ss = ss;
    }

    public void run() {
        for(int i=0; i<20; i++) {
            WoTou wt = ss.pop();
System.out.println("消费了: " + wt);
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
时间: 2024-09-30 15:48:10

马老师的WoTou生产消费线程讲解例子的相关文章

3、传统线程同步与通信--生产消费例子

核心点: 1.锁对象必须是同一个. 2.wait()和notify()方法必须是调用锁对象的方法,而非this(线程)的. 3.在多生产多消费的时候注意使用notifyAll而不是notifyAll,否则会造成死锁 测试代码: 1 import java.util.LinkedList; 2 import java.util.Queue; 3 import java.util.Random; 4 5 /** 6 * 多个生产 - 消费 线程同步通信 7 * 核心点: 8 * 1.锁对象必须是同一

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力. 什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待

生产消费

线程同步 class SynStack { private char data[] = new char[6]; private int cnt = 0;// 表示数组有效元素的个数 public synchronized void push(char ch) { while (data.length == cnt) { try { this.wait(); } catch (Exception e) { } } this.notify(); data[cnt] = ch; cnt++; Sys

【51CTO学院三周年】聆听小马老师授课,技能大增啊

大家好,我是2012年注册的51CTO会员帐号.我之前一直学程序开发,对数据分析,大数据这些内容很感兴趣,linux系统管理也有兴趣.51CTO汇集了好多IT名师大家的授课,内容很丰富,对我的学习帮助很大. 去年下半年打算学习HadoopMapreduce,而要搭建这个计算环境,必须先搭建双机或多机的Linux操作系统,所以首先要学习Linux课程,我选择了上座率最高的小马老师的课,结果一下子就被小马老师的授课风格给吸引了,他授课完全脱离课本教材,不是照本宣科的那种,语言诙谐,幽默风趣,善于用生

【JAVA】wait和notify用法,附生产/消费模型

关于wait和notify的用法,网上已经有很多详细解释了,我只是简单的总结下. wait用于释放锁A,并让wait所在的线程阻塞.除非被持有锁A的其它线程执行notify来唤醒,它才能重新"活"过来. notify用于唤醒因为等待锁A而阻塞的线程,让它们做好竞争锁A的准备.如果有多个线程因等待锁A而被阻塞,notify只唤醒一个,唤醒所有用notifyAll. 参考下面的线程状态图,对理解wait和notify有很大的帮助. 总结: wait和notify通常和synchronize

RocketMQ专题2:三种常用生产消费方式(顺序、广播、定时)以及顺序消费源码探究

顺序.广播.定时任务 前插 ? 在进行常用的三种消息类型例子展示的时候,我们先来说一说RocketMQ的几个重要概念: PullConsumer与PushConsumer:主要区别在于Pull与Push的区别.对于PullConsumer,消费者会主动从broker中拉取消息进行消费.而对于PushConsumer,会封装包含消息获取.消息处理以及其他相关操作的接口给程序调用 Tag: Tag可以看做是一个子主题(sub-topic),可以进一步细化主题下的相关子业务.提高程序的灵活性和可扩展性

Java生产消费模型—ArrayBlockingQueue详解

背景需求 生产消费模型是线程协作关系中十分常见的一种.通常,一个(多个)线程负责生产,一个(多个)线程可以从生产的列表中获取并消费:生产的内容可以按需求设计,可以是一个Integer,可以是String,可以Object,也可以是任意类型的对象,只要有生产消费的需求. 例如,厨师负责生产美食,放在桌子上,服务员负责取走(消费)美食.这里,厨师就扮演着生产者的身份,美食是生产的内容,服务员就扮演着消费者的身份. 下面用这个厨师与服务员的案例来分析下生产消费模型需要实现哪些功能才能满足需求: 如何实

有感追随马老师的过考之路(转自学员)

今天查了成绩,看到都在45分之上后,第一反应是,按照马老师要求的去做,真心是过考的法宝.为了发这个帖子,特意按照马老师建议注册了论坛账号,下面给给各位考友简单分享下我的备考经历. 1 注重方法.上午选择,下午案例,都需要沉下心来去学,跟着马老师讲课视频第一.二遍把教材先熟悉了,后面再跟着马老师题目书把知识点巩固了.前面的基础知识掌握熟了,后面再加上专门有案例课程,上午选择和下午案例基本就过了.论文方面,在一开始时候马老师就给大家说不要放太多精力尤其是一开始时候,主要精力应放在上午选择上,上午基础

1个争用资源的简单线程小例子

main()本身就是一线程,现在在main内部再创建另一个线程, 例子只是简单的在两个线程中打印了一下TID和PID以及获取本身PID,当然两个线程的TID是一样的,PID是不一样的. 这里主要说的是:两个线程一起运行,屏幕上显示的各线程的内容,因为一起争用资源,造成了打印信息内容的重叠. 代码: #include <iostream> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #i