实现生产者消费者进程(Java)

目录

前言 

一、实验要求

二、步骤

1.主类

2.消费者

 3.生产者

4.超市


前言 

消费者问题是操作系统中典型的进程同步互斥问题,(英语:Producer-Consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个进程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程“生产者”(Producer)和“消费者”(Consumer)在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。问题的约束条件是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中为空时消耗数据。


一、实验要求

  1. 互斥信号量和资源信号量的使用
  2. 互斥信号量初始值为1来表示(同步于操作系统书),同步信号量用0表示(本文没有涉及到)。
  3. 最大存放空间为10。
  4. 消费者不可以在没有产品的时候进行消费。
  5. 消费者和生产者是两个线程
  6. 生产和消费这两个线程执行时,生产者或者消费者不会一直执行相应的方法。(是穿插着来的)

二、步骤

1.主类

代码如下(示例):

  • 实例化俩个实现Runnable接口的对象


import com.os.util.Consumer;
import com.os.util.Producer;
import com.os.util.Supermarket;

/**
 * 主类
 */
public class Main {
    public static void main(String[] args) {
        Supermarket supermarket = new Supermarket();
        Consumer consumer = new Consumer(supermarket);
        Producer producer = new Producer(supermarket);
        Thread
                t1 = new Thread(consumer,"消费者"),
                t2 = new Thread(producer,"生产者");
        t1.start();
        t2.start();
    }
}

2.消费者

代码如下(示例):

  • 死循环执行消费方法


/**
 * 消费者
 */
public class Consumer implements Runnable{
    private Supermarket supermarket;

    public Consumer(Supermarket supermarket) {
        this.supermarket = supermarket;
    }

    @Override
    public void run() {
        while (true) {
            supermarket.consume();
        }
    }
}

 3.生产者

代码如下(示例):

  • 死循环执行生产方法
/**
 *生产者
 */
public class Producer implements Runnable{
    private Supermarket supermarket;

    public Producer(Supermarket supermarket) {
        this.supermarket = supermarket;
    }

    @Override
    public void run() {
        while (true) {
            supermarket.product();
        }
    }
}

4.超市

/**
 * 互斥信号量
 * 1:生产者正在执行此时消费者等待,生产者执行完毕之后,消费者再去执行。
 * 0:消费者正在执行此时生产者等待,消费者执行完毕之后,生产者再去执行。
 *
 * wait()和 notify()是一对互斥锁 相对于wait()和signal()
 * wait()是进行等待,当前线程处在阻塞状态
 * notify()是唤醒线程
 */

 

代码如下(示例):

public class Supermarket {

    private static int mutex = 1;  //互斥信号量
    private static final int max = 10;  //可放最大空间
    private  int count; //统计产品数量

    public synchronized void product() {
        if (mutex == 0 && this.count >= max) {
            try {
                this.wait();//线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }//互斥信号量为0 且生产的数量小于超市可放的最大数量()
        else {
            count++;//生产产品
            System.out.println(Thread.currentThread().getName() + "生产 +1,剩余:" + count);
            this.notify();//唤醒线程
            mutex = 0;//消费者进行消费
            try {
                Thread.sleep(500);//避免当前线程再次进入该方法,执行线程等待半秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void consume() {
        if (this.count == 0 && mutex==1) {
            try {
                this.wait();//线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //mutex=0且 count !=0
        } else {
            count--;//消费产品
            System.out.println(Thread.currentThread().getName() + "消费 -1,剩余:" + count);
            this.notify();//唤醒线程
            mutex = 1;
            try {
                Thread.sleep(500);//避免当前线程再次进入该方法,执行线程等待半秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 三、运行结果

  • 可能每次的运行结果不用,但是都满足实验要求。

 

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值