会员可以在此提问,百战程序员老师有问必答
对大家有帮助的问答会被标记为“推荐”
看完课程过来浏览一下别人提的问题,会帮你学得更全面
截止目前,同学们一共提了 132647个问题
JAVA 全系列/第二阶段:JAVA 基础深化和提高/反射技术 271楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器 272楼

package com.itbaizhan;

class manTou{
    private int id;

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

    public int getId() {
        return id;
    }
}

//定义缓冲区 不是线程类
class SyncStack{
    //定义放馒头的容器
    private manTou m[] = new manTou[10];

    //索引
    int i;

    //放馒头
    public synchronized void push(manTou mantou){
        //判断是否满了
        while(i == m.length) {  //用while多判断几次防止当前线程没有执行而忽略
            try {
                this.wait(); //object类的方法,必须在syn调用,线程的对象锁解放,并且进入堵塞状态
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.notify();  //唤醒等待序列中的一个线程
        this.m[i] = mantou;
        i++;

    }

    //取馒头
    public synchronized manTou pop() {
        //判断是否满了
        while (i == 0) {  //用while多判断几次防止当前线程没有执行而忽略
            try {
                this.wait(); //object类的方法,必须在syn调用,线程的对象锁解放,并且进入堵塞状态
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.notify();  //唤醒等待序列中的一个线程
        i--;
        return m[i];

    }

}

//定义生产者线程
class shengchan extends Thread{
    private SyncStack s;

    public shengchan(SyncStack s) {
        this.s = s;
    }

    @Override
    public void run() {
        for(int i = 0; i<10; i++){
            System.out.println("生产馒头" + i);
            manTou m = new manTou(); // 每次循环都创建一个新的馒头并放入stack里

            s.push(m);

        }
    }
}

class xiaofei extends Thread{
    private SyncStack s;

    public xiaofei(SyncStack s) {
        this.s = s;
    }

    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            System.out.println("取馒头" + i);
            manTou m = s.pop();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ProducerThread {
    public static void main(String[] args) {
        //创建缓冲区
        SyncStack s = new SyncStack();

        //创建生产线程
        shengchan produce = new shengchan(s);
        produce.start();

        //创建消费线程
        xiaofei consumer = new xiaofei(s);
        consumer.start();

    }
}

QQ图片20230207232704.png

这里两个线程锁的都是同一个对象,那按理说应该等生产线程执行完再执行消费啊,为什么还是并发执行的?

JAVA 全系列/第二阶段:JAVA 基础深化和提高/多线程技术 273楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/数据结构 274楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器 276楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/数据结构 277楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/函数式编程 281楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器 282楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/容器 283楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/网络编程 284楼
JAVA 全系列/第二阶段:JAVA 基础深化和提高/多线程技术 285楼

课程分类

百战程序员微信公众号

百战程序员微信小程序

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