Java 实现生产者与消费者问题

2023-11-12

生产者与消费者问题

问题简述:

  • 一群生产者进程在生产产品,并将这些产品提供给消费者去消费。为了使生产者进程与消费者进程能够并发进行,在两者之间设置一个具有n个缓冲区的缓冲池,生产者进程将产品放入一个缓冲区中;消费者可以从一个缓冲区取走产品去消费。尽管所有的生产者进程和消费者进程是以异方式运行,但它们必须保持同步:当一个缓冲区为空时不允许消费者去取走产品,当一个缓冲区满时也不允许生产者去存入产品。

具体实现:

package producterComsumer;

import java.util.LinkedList;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class SemaphorePC  {

    public static int count = 0;
    public static int band = 0;
    public Random random = new Random();

    public static int buffer[] = new int[10];  //缓存区
    public static int position = 0; //缓存区下标
    LinkedList<Integer> goods = new LinkedList<Integer>();

    final Semaphore notFull = new Semaphore(10);
    final Semaphore notEmpty = new Semaphore(0);
    final Semaphore mutex = new Semaphore(1);
    
    public static void main(String[] args){

        SemaphorePC pc = new SemaphorePC();

       
        for(int i=0;i<10;i++){   //初始化缓存区
            buffer[i] = -1;
        }
        //while(true){
            new Thread(pc.new Producer()).start();
            new Thread(pc.new Consumer()).start();
            new Thread(pc.new Producer()).start();
            new Thread(pc.new Consumer()).start();
            new Thread(pc.new Producer()).start();
            new Thread(pc.new Consumer()).start();
        //}

       // new Thread(pc.new Producer()).start();


    }

    public void print(){
        for(int i=0;i<10;i++){
            if(buffer[i]!=-1)
                System.out.printf("%10d",buffer[i]);
            else
                System.out.print("      "+null);
        }
        System.out.println("\n");
        //createAndShowGUI(buffer);
    }

    class Producer implements Runnable{


        public Producer(){}
        @Override
        public void run() {
            for (int i = 0; i < 30; i++) {
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    notFull.acquire();
                    mutex.acquire();
                    count++;
                    band++;
                    while(true){
                        //position++;
                        if(buffer[position=random.nextInt(10)]  == -1){
                            buffer[position] = band;
                            break;
                        }
                               // position = position %10;
                    }
                    String name = Thread.currentThread().getName();
                    if(name.equals("Thread-0")){
                        name = "producter 1 ";
                    }
                    else if(name.equals("Thread-2")){
                        name = "producter 2 ";
                    }
                    else if(name.equals("Thread-4")) {
                        name = "producter 3 ";
                    }
                    System.out.println(name+"生产了i一个商品"+band);
                    print();
                    //goods.add(band);
                    //System.out.println("生产者生产了一个商品,ID:"+band);
                    //System.out.println(Thread.currentThread().getName()
                    //        + "目前总共有" + count+"的商品");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    mutex.release();
                    notEmpty.release();
                }
            }

        }
    }

    class  Consumer implements Runnable{


        @Override
        public void run() {
            for(int i=0;i<30;i++){

            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            try {
                notEmpty.acquire();
                mutex.acquire();
                count--;
                int temp;
                while(true){
                    //position++;
                    if(buffer[position=random.nextInt(10)]  != -1){
                        temp = buffer[position];
                        buffer[position] = -1;
                        break;
                    }
                    // position = position %10;
                }
                //System.out.println("生产者生产了一个商品"+band);

                String name = Thread.currentThread().getName();
                if(name.equals("Thread-1")){
                    name = "comsumer 1 ";
                }
                else if(name.equals("Thread-3")){
                    name = "comsumer 2 ";
                }
                else if(name.equals("Thread-5")) {
                    name = "comsumer 3 ";
                }


                System.out.println(name+"消耗了商品 "+temp);
                print();   //输出
                //goods.remove(0);
                //System.out.println(Thread.currentThread().getName()
                //        + "目前总共有" + count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                mutex.release();
                notFull.release();
            }
        }


    }
    }

}





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 实现生产者与消费者问题 的相关文章

  • Mac OS X のキーボードショートカット

    概要 記事 Mac OS X 一般的 紹介 使 上 組 合 同時 押 Mac OS X 機能 呼 出 操作 利用 修飾 文字 同時 押 現在選択 範囲 貼 付 command 刻印 C 同時 押 操作 command C 呼 修飾 多数 組
  • 《30天自制操作系统》入门方法总结

    30天自制操作系统 是一位日本大佬 川合秀实 老师所写的一本书 逻辑清晰 语言朴实 我跟着中文版的电子书学习了两天 感觉很好 在这里我就实操环节简单做一下总结 以帮助初学者更好的入门 1 操作系统和编辑器 我使用的是win10 64位 专业
  • android 开发之Activity切换

    img http dl iteye com upload attachment 434571 821c3369 a3bd 357a a260 e5ebe255fa6c jpg img img http dl iteye com upload
  • Python实现读取目标文件夹数据,并将目标数据复制到指定文件夹

    前言 本文是该专栏的第34篇 后面会持续分享python的各种干货知识 值得关注 假设工作上遇到这样的需求 需要用python读取目标文件夹里面的数据 数据可能包含各种doc文档 pdf文档以及excel文档数据 甚至其它各种类别的类型数据
  • python中os模块中文帮助文档

    python中os模块中文帮助文档 翻译者 butalnd 翻译于2010 1 7 2010 1 8 个人博客 url http butlandblog appspot com url 注此模块中关于unix中的函数大部分都被略过 翻译主要
  • MIT 6.s081学习笔记

    MIT 6 s081学习笔记 introduction 计算机组织结构 最底部是一些硬件资源 包括了CPU 内存 磁盘 网卡 最上层会运行各种应用程序 比如vim shell等 这些就是正在运行的所有程序 它们都运行在同一个空间中 这个空间
  • android中完全退出当前应用程序的四种方法

    Android程序有很多Activity 比如说主窗口A 调用了子窗口B 如果在B中直接finish 接下里显示的是A 在B中如何关闭整个Android应用程序呢 本人总结了几种比较简单的实现方法 1 Dalvik VM的本地方法 andr
  • 虚拟机安装linux系统,重启后无法联网

    虚拟机安装linux系统 重启后无法联网 使用环境 触发问题 临时解决问题 使用环境 manjaro 18 deepin15 8 fedoras 29 等 有nmcli网络套件管理 无法使用systemctl restart network
  • os.getcwd()函数的用法

    获得当前路径 在Python中可以使用os getcwd 函数获得当前的路径 其原型如下所示 os getcwd 该函数不需要传递参数 它返回当前的目录 需要说明的是 当前目录并不是指脚本所在的目录 而是所运行脚本的目录 gt gt gt
  • NStepSCAN和FSCAN

    NStepSCAN 在最短寻道时间优先 SSTF 扫描算法 SCAN 和循环扫描算法 CSCAN 中 都可能出现磁臂停留在某处不动的情况 例如 有一个或几个进程对某一磁道有较高的访问频率 这些进程反复请求对某一磁道的I O操作 从而垄断了整
  • golang cli_Go CLI教程:财富克隆

    golang cli I ve written two CLI app tutorials to build gololcat and gocowsay In both I used fortune as the input generat
  • ubuntu修改镜像源步骤

    手动修改镜像源 1 百度找到镜像源地址并打开 传送门 https mirrors tuna tsinghua edu cn help ubuntu 2 修改存放镜像源的文件 3 执行命令生效 如 将镜像源改成清华大学TUNA镜像源 http
  • java中yield(),sleep()以及wait()的区别

    往往混淆了这三个函数的使用 从操作系统的角度讲 os会维护一个ready queue 就绪的线程队列 队列 是先进先出的 FIFO 并且在某一时刻cpu只为ready queue中位于队列头部的线程服务 但是当前正在被服务的线程可能觉得cp
  • 深入理解计算机系统(原书第三版)系列 第十一章 网络编程

    第十一章 网络编程
  • 《实现VM机与本机互ping》

    实现VM机与本机互ping 1 安装VM机及对应的OS gt 到本机检测VMware Network Adapter VMnet8是否已经生成 网上邻居 网络连接 2 查看 VMware Network Adapter VMnet8 网络I
  • 用python编写递归爬取多重网址的网站信息

    项目组要得到这个http kalug linux org tw shawn project thesis 目录网址下面的所有文件以及这个文件目录的下层目录以及更下层目录的文件包括这个 用迅雷 flashget好像都没这样的功能 找到给一个链
  • Ubuntu16.04安装ROS Kinetic详细步骤

    文章目录 ROS安装 配置Ubuntu软件仓库 设置sources list 设置密钥 更新Debian软件包索引 安装ROS 初始化 rosdep 环境配置 构建工厂依赖 测试安装 开发环境 ROS安装 ROS Kinetic只支持Wil
  • OS中 main.h 的一些基本概念 以及 类与对象的概念及其实现

    目录 头文件 import lt gt 与 import 的区别 include 与 import 的区别 OC语言的特点 自动释放池 面向对象的 特征 与 概念 以及其基本思想 类 与 对象 的概念 如何用OC中创建与使用对象 如何给对象
  • 【转】Adapter应用总结

    Adapter应用总结 首先来看一下Adapter的体系结构 一个Adapter的对象扮演一个桥梁的角色 这个桥梁连接着一个AdapterView和它所包含的数据 Adapter提供了一个通到数据项的途径 Adapter还负责为在数据集里的
  • 内核虚拟化KVM/QEMU——guest os,qemu,kvm的运行流程

    内核虚拟化KVM QEMU guest os qemu kvm的运行流程 这里主要介绍基于x86平台的Guest Os Qemu Kvm工作流程 如图 通过KVM APIs可以将qemu的command传递到kvm 1 创建VM syste

随机推荐

  • 整理了27个Python人工智能库,建议收藏

    为了大家能够对人工智能常用的 Python 库有一个初步的了解 以选择能够满足自己需求的库进行学习 对目前较为常见的人工智能库进行简要全面的介绍 1 Numpy NumPy Numerical Python 是 Python的一个扩展程序库
  • ssd m.2接口详解

    ssd有两种接口 一种是sata 一种是m 2 这里主要深入讲解一下m 2接口的ssd 1 ssd 尺寸与规格 我们在买ssd的时候 商家都会说什么ssd是2280还是2242规格的 这里的规格实际上就是代表的ssd的大小 M 2模组的尺寸
  • pytrch手写数字识别

    使用Pytorch实现手写数字识别 目标 知道如何使用Pytorch完成神经网络的构建 知道Pytorch中激活函数的使用方法 知道Pytorch中torchvision transforms中常见图形处理函数的使用 知道如何训练模型和如何
  • Unity:利用 射线Ray 检测物体

    利用 射线Ray 检测物体 Unity射线 Ray 是通过发射一条射线来检测碰撞体或触发器 不带碰撞器组件的物体时无法检测的 可以在物理设置里取消检测触发器 Edit Project Setting Physics Physics2D Ph
  • Spring Boot中的Dozer和MapStruct比较

    Spring Boot中的Dozer和MapStruct比较 在Java开发中 数据对象之间的转换是一个常见的任务 Spring Boot作为一个流行的Java框架 提供了多种方式来处理对象之间的转换 两个常用的工具是Dozer和MapSt
  • call、apply、bind方法详解

    1 每个函数都包含两个非继承而来的方法 call 方法和apply 方法 2 相同点 这两个方法的作用是一样的 只是传参方式不一样而已 call 方法使用 window msg 1 document msg 2 var log msg 3
  • springboot 如何修改控制台输出的图案

    如图 操作步骤 1 在项目的resource文件夹下 新建一个文件命名为banner txt 2 进入网站 http patorjk com software taag p display h 0 v 0 f Big t SpringBoo
  • Spring WebSocket通信应用

    文章目录 前言 一 客户端 服务端双向通信交互图 二 项目说明 1 引入包 2 项目各模块说明 问题 参考 前言 本文章主要记录项目客户端 服务端双向通信解决方案 基于Spring WebSocket架构实现双向数据通信 以及项目实际应用中
  • 【SQLAlchemy】第二篇——连接失效及连接池

    一 背景 为了节约资源 MySQL会对建立的连接进行监控 当某些连接处于不活跃状态的时间超过一个阈值时 则关闭它们 用户可以执行show variables like wait timeout 来查看这个阈值 可以看到 在默认的情况下 这个
  • 04-8_Qt 5.9 C++开发指南_QTableWidget的使用

    文章目录 1 QTableWidget概述 2 源码 2 1 可视化UI设计 2 2 程序框架 2 3 qwintspindelegate h 2 4 qwintspindelegate cpp 2 5 mainwindow h 2 6 m
  • VisionWorks快速入门--Graph Mode

    VisionWorks快速入门 Graph Mode 从立即模式过渡到图形模式 1 创建新节点 2 向GraphModestabilizer类添加新字段和函数 3 初始化字段 4 执行算法的迭代 5 Release objects 结果 本
  • 解决科研人痛点的大突破:Zotero 6.0 版有哪些亮点?

    痛点 翻了翻日记 发现我第一次使用 Zotero 文献管理器的时间 是 2008 年 12 月 19 日 这中间曾经因为论文写作需要处理中文文献等原因 若干次切换过其他的文献管理器 包括 NoteExpress 和 Mendeley 等 几
  • IIS站点发布log

    1 启用IIS服务 2 打开IIS管理界面 3 添加站点 4 填写站点信息 1 物理路径为发布的log文件目录 2 填写IP地址和端口 5 发布的log文件设置权限 添加Everyone用户 并设置权限 6 启动站点 浏览器访问 此时出错
  • city_picker改造-------五级城市联动控件

    这几天做项目 需要用到城市控件 网上找了个样式不错的控件 基于bootstrap的 具体用法可以参照https blog csdn net bsw451926392 article details 78886965 但是我这边需要精确到村级
  • vscode的vue中出现很多红色波浪线解决办法

    vscode的vue中出现很多红色波浪线 看上去就很烦 如下所示 这么看呢 代码没什么问题 为什么有那么多红色波浪线呢 其实出现这个的原因是代码和vetur插件的格式不对应 解决办法 1 严格遵循vetur的格式去写 不过麻烦 2 关闭ve
  • 区块链系统面临哪些风险以及有哪些防范措施

    区块链是涉及多方的开放系统 早期的应用又与虚拟加密货币相关 由此使得区块链系统所内含的和面对的风险得以暴露 同时各种安全措施也得以被及时使用和验证 但区块链在真实世界的大规模应用尚未展开 因此区块链所内含以及面临的风险暴露尚不完全 预防措施
  • 【linux服务器编程学习】10.多线程编程

    linux中的线程 线程是linux中完成一个独立任务的完整执行序列 即一个可调度的实体 根据运行环境 可分为内核线程和用户线程 分别由内核和程序线程库调度 关于linux多线程编程 需要掌握怎么创建和结束线程 怎么读取和设置线程属性 线程
  • macOS中如何使用OpenGL 3.2 Core Profile

    从macOS Lion 10 7 开始 Apple支持了对OpenGL 3 2 Core Profile的支持 不过Core Profile与Compatible相比有比较大幅度的改变 从主机端的API到OpenGL接口 再到GLSL Op
  • ISP DSP的区别

    ISP 是Image Signal Processor 的简称 也就是图像信号处理器 而DSP是Digital Signal Processor 的缩写 也就是数字信号处理器 ISP一般用来处理Image Sensor 图像传感器 的输出数
  • Java 实现生产者与消费者问题

    生产者与消费者问题 问题简述 一群生产者进程在生产产品 并将这些产品提供给消费者去消费 为了使生产者进程与消费者进程能够并发进行 在两者之间设置一个具有n个缓冲区的缓冲池 生产者进程将产品放入一个缓冲区中 消费者可以从一个缓冲区取走产品去消