会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 132437个问题
Python 全系列/第七阶段:网页编程基础/CSS3 6557楼
JAVA 全系列/第三阶段:数据库编程/JDBC技术 6559楼
JAVA 全系列/第九阶段:权限控制与安全认证/Spring Security(旧) 6562楼
JAVA 全系列/第十八阶段:亿级高并发电商项目/亿级高并发电商项目(旧) 6563楼
JAVA 全系列/第七阶段:生产环境部署与协同开发/Docker 6565楼
JAVA 全系列/第十二阶段:Spring Cloud Alibaba技术栈/Dubbo 6566楼
JAVA 全系列/第十二阶段:Spring Cloud Alibaba技术栈/Dubbo 6567楼

//测试生产者消费者模式,创建缓冲区
//创建生产者与消费者线程
//定义馒头类
class ManTou{
    private int id;
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

//定义缓冲区
class SyncStack{ //就是一个存放数据的地方,不需要实现Runnable接口也不需要继承Thread
    //定义存放馒头的盒子
    private ManTou[] mt = new ManTou[10];

    //定义操纵盒子的索引
    private int index;//默认为0

    //放馒头
    public synchronized void push(ManTou mantou){
        //判断盒子是否已满
       while(this.index==this.mt.length){
            try {
                //Object类下的一个方法,执行后,线程会将持有的对象锁释放,并进入阻塞状态。其他需要该对象锁的线程可以继续运行。该方法必须在synchronized块中调用
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notify();//唤醒取馒头的线程
        this.mt[this.index] = mantou;
        this.index++;
    }

    //取馒头
    public  synchronized ManTou pop() {
        while (this.index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //该方法必须要在synchronized块中调用。会唤醒处于等待状态队列当中的一个线程
        this.notify();//唤醒生产馒头的线程
        this.index--;
        return this.mt[this.index];
    }
}

//定义生产者线程类
class Producer extends Thread{
    private SyncStack ss;
    public Producer(SyncStack ss){
        this.ss = ss;
    }

    @Override
    public void run() {
        for(int i=0;i<10;i++){
            ManTou mt = new ManTou();
            mt.setId(i);
            System.out.println("生产馒头:"+mt.getId());
            this.ss.push(mt);//调用push方法把馒头放到定义好的缓冲区(数组)里
        }
    }
}

//定义消费者线程
class Consumer extends Thread{
    private SyncStack ss;//和生产者是同一个缓冲区
    public Consumer(SyncStack ss){
        this.ss = ss;
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            ManTou mt = this.ss.pop();
            System.out.println("消费馒头:"+mt.getId());
        }
    }
}

public class TestProduceThread {
    public static void main(String[] args) {
        //创建缓冲区
        SyncStack ss = new SyncStack();
        //创建生产者线程
        new Producer(ss).start();
        //创建消费者线程
        new Consumer(ss).start();
    }
}

为什么我的结果每一次都是生产者生产完再是消费者消费?这难道不是一个并发的过程吗?应该我生产了就提醒消费者取了呀,但是消费者等生产完才取的

JAVA 全系列/第二阶段:JAVA 基础深化和提高/多线程技术 6568楼
JAVA 全系列/第一阶段:JAVA 快速入门/面向对象详解和JVM底层内存分析 6570楼

课程分类

百战程序员微信公众号

百战程序员微信小程序

©2014-2025百战汇智(北京)科技有限公司 All Rights Reserved 北京亦庄经济开发区科创十四街 赛蒂国际工业园
网站维护:百战汇智(北京)科技有限公司
京公网安备 11011402011233号    京ICP备18060230号-3    营业执照    经营许可证:京B2-20212637