java多线程生产者消费者问题

本文详细介绍了生产者消费者问题在多线程编程中的应用,通过使用同步机制解决并发问题,保证了生产者和消费者的同步。文中提供了一个Java实现的示例,展示了如何使用synchronized关键字和wait/notify方法来协调生产者和消费者线程,确保同一时间只有一个生产者或消费者操作共享资源。
摘要由CSDN通过智能技术生成

 

生产者消费者是多线程的一个经典问题,在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。生产者消费者描述的是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品,即生产者和消费者在同一个时间段内共用同一个存储空间。如果在正常情况下不加以协调,当存储空间已满,生产者占用着它,消费者等着生产者让出空间从而拿走产品,生产者等着消费者消费产品,从而向空间中添加产品。互相等待,从而发生死锁。

解决生产者消费者问题的方法一般采用同步机制保证生产者和消费者之间的同步,这种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。

同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。Java语言在多线程编程上实现了完全对象化,提供了对同步机制的良好支持。

生产者与消费者模型中,要保证以下几点:

1. 同一时间内只能有一个生产者生产 生产方法加锁sychronized
2. 同一时间内只能有一个消费者消费 消费方法加锁sychronized
3. 共享空间空时消费者不能继续消费 消费前循环判断是否为空,空的话将该线程wait,释放锁允许其他同步方法执行
4. 共享空间满时生产者不能继续生产 生产前循环判断是否为满,满的话将该线程wait,释放锁允许其他同步方法执行
 


//店员类
class Clerk{
    //产品数
    private Integer number=0;
    //生产产品方法
    public synchronized void provide() {
        if(number<20){
            notify();//唤醒
            System.out.println(Thread.currentThread().getName()+"开始生成第"+number+"个产品");
            number++;
        }else {
            try {
                wait();//阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //消费产品方法
    public synchronized void customer() {
        if(number>0){
            notify();//唤醒
            System.out.println(Thread.currentThread().getName()+"开始生成第"+number+"个产品");
            number--;
        }else {
            try {
                wait();//阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//生产者线程
class Provider extends Thread{
    private Clerk clerk;

    public Provider(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        System.out.println(getName()+"开始生成产品");
        while (true){
            try {
                sleep(10);//休息十毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.provide();//调用生产者方法
        }
    }
}
//消费者线程
class Customer extends Thread{
    private Clerk clerk;

    public Customer(Clerk clerk) {
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println(getName()+"开始消费产品");
        while (true){
            try {
                sleep(10);//休息十毫秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.customer();//调用消费者方法
        }
    }
}
public class Provice {
    public static void main(String[] args) {
        //定义一个店员
        Clerk clerk=new Clerk();
        //创建生成者线程
        Provider p=new Provider(clerk);
        //创建消费者线程
        Customer c=new Customer(clerk);
        p.setName("生产者1");
        c.setName("消费者1");
        p.start();
        c.start();
    }
}

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海很远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值