Java多线程操作案例-生产者和消费者实现

本文通过Java多线程实现生产者消费者模式,介绍如何利用synchronized关键字及线程等待唤醒机制确保资源正确访问。代码示例包括主类、电脑类、仓库类、生产者类和消费者类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生产者和消费者问题是线程操作中的一个经典案例,本文采用Java多线程来实现这一经典问题。
1、使用Java来实现,首先要分析这个问题需要几个类来实现:
(1)这个问题本身就是一个类,即主类 ;
(2)要有生产者类和消费者类;
(3)生产什么,消费什么,所以需要一个物品类,这里使用电脑类 ,表示生产和消费电脑;
(4)多线程操作,需要对资源区的资源进行异步操作,即生产的电脑需要一个仓库存放,消费电脑也需要从这个仓库取出来,因此需要一个盛放电脑的仓库类。

2、解决这个问题要注意:
(1)生产者和消费者可能会同时对资源区(仓库)进行异步操作,会导致仓库内电脑数量不一致,因此要使用Java中的synchronized关键字对存放电脑和取出电脑的操作进行同步。
(2)如果仓库已满,则生产者线程阻塞,需要等待;如果仓库为空,则消费者线程阻塞需要等待,因此需要使用Java中的一些线程的等待和唤醒的方法。

public class Procon {            //主类
    public static void main(String[] args) {  
        Repertory rep = new Repertory(5);//新建一个存放电脑的仓库  
        Producer p = new Producer(rep);//新建一个生产者对象,使用rep仓库  
        Consumer c = new Consumer(rep);//新建一个消费者对象,使用同一个rep仓库  
        Thread pt = new Thread(p);//生产者线程  
        Thread ct = new Thread(c);//消费者线程 
        pt.start();//启动生产者线程 
        ct.start();//启动消费者线程  
    }  
}



//电脑类  
class Computer{  
    int id;//电脑编号
    Computer(int id){  
        this.id = id;  
    }  
    public String getComputer(){  
        return "Computer:"+this.id;  
    }  
}  

//仓库类 
class Repertory{  
    private int length; //仓库大小 
    private Computer[] compArrey;//具体存放电脑的位置
    private int index;//仓库位置的索引
    Repertory(int len){
        this.length = len;
        this.index = 0;
        compArrey = new Computer[len];//构造电脑对象数组,在这个仓库中开辟存放电脑的空间
    }  
    //将电脑放入仓库的方法,使用synchronized来保持仓库数据的同步 
    public synchronized void push(Computer c){  
        while(this.index == this.length){//如果仓库满了,需要生产者线程等待  
            try {  
                this.wait();//让当前线程等待 
            } catch (InterruptedException e) {   
                e.printStackTrace();  
            }  
        }  
        this.notify();//唤醒在此对象监视器上等待的单个线程,即消费者线程  
        this.compArrey[index] = c;  
        this.index++;  
    }  

    //从仓库中取出电脑 
    public synchronized Computer pop(){  
        while(this.index == 0){//如果仓库为空,需要消费者线程等待  
            try {  
                this.wait();  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
        this.notify();  
        this.index--;  
        return this.compArrey[index];  
    }  
}  

//生产者类实现Runnable接口,用于构造生产者线程 
class Producer implements Runnable{  
    private Repertory rep; //使用的仓库
    Producer(Repertory rep){  
        this.rep = rep;  
    }  
    @Override  //重写run方法
    public void run() {  
        // 开始生产电脑 
        for(int i=0;i<10;i++){  
            Computer c = new Computer(i);  
            this.rep.push(c);  
            System.out.println("生产了"+c.getComputer());  
            try {  
                Thread.sleep(10);//每生产一台电脑,线程休眠10毫秒  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
}  

//消费者类实现Runnable接口,用于构造消费者线程 
class Consumer implements Runnable{  
    private Repertory rep; //使用的仓库 
    Consumer(Repertory rep){  
        this.rep = rep;  
    }  
    @Override  
    public void run() {   
        for(int i=0;i<10;i++){//开始消费电脑 
            Computer c = this.rep.pop();  
            System.out.println("消费了"+c.getComputer());  
            try {  
                Thread.sleep(100);//每消费一台电脑,消费者线程休眠100毫秒 
            } catch (InterruptedException e) {   
                e.printStackTrace();  
            }  
        }  
    } 
 }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值