BUAA-OO-UNIT 2

唐风·绸缪 唐风·绸缪 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

第一次作业

设计与架构

第一次作业参考了课上实验的代码,采用生产者消费者模型
设计出Main、PassengersQueue、ProcessingQueue、InputThread、Scheduler、Elevator六类

其中InputThread、Elevator、Scheduler为线程类

  • InputThread处理输入

  • Scheduler分配请求

  • Elevator处理请求

处理流程如下

img

需要读写的类:PassengersQueue 、ProcessingQueue

考虑到同步逻辑并不复杂,使用synchronized修饰以上两类的方法,可以很好地保证操作的原子性

调度策略

本次作业的乘客请求指定了乘坐的电梯,无需赘述

运行策略

将分配至ProcessingQueue的请求分类为 upQueue 和 downQueue
在Elevator中设置变量 state ,有 MOVING_DOWN 、MOVING_UP 、IDLE 三种状态

  • 当state为MOVING_UP时,查找 upQueue中fromFloor大于nowFloor的请求的toFloor 和 downQueue中fromFloor大于nowFloor 的最大值
  • 当state为MOVING_DOWN时,查找 downQueue中fromFloor小于nowFloor的请求的toFloor 和 upQueue中fromFloor小于nowFloor 的最小值
  • 当state为IDLE时,查找upQueue和downQueue中 fromFloor大于nowFloor的请求数量 和 fromFloor小于nowFloor的请求数量,将数量多的一方设置为运行方向

这种策略可以保证elevator在往返时,满足电梯中的乘客请求,同时捎带尽可能多的乘客,还可以尽量避免出现极端情况下某些乘客被“饿死”的情况
为了优先满足高优先级乘客请求,将upQueue、downQueue设置为PriorityQueue

第二次作业

第二次作业并未指定乘客请求的乘坐电梯,同时,新增了SCHE请求

需要修改Scheduler类中的分配策略,增加Elevator中对SCHE请求的处理

此次作业,笔者将 synchronized修饰 更改为 ReadWriteLock ,希望能允许多个读操作并发执行,提高运行效率,虽然对性能几乎没有任何影响

分配策略

笔者设计了一个基于电梯状态、电梯负载、电梯楼层、待处理队列的估分分配策略

略微进行了参数调整,性能强于随机分配

private int evaluateElevator() {
        // 1. 方向适配性(优化运行时间 & 耗电)
        if (...) {
            if (...) {
                 // 方向一致且顺路
            } else if () {
                // 方向一致但逆路
            }
        } else if (...) {
            if (...) {
                 // 方向一致且顺路
            } else if (...) {
                // 方向一致但逆路
            }
        } else if () {
            // 空闲电梯更高基础分
        }

        // 2. 距离评分

        // 3. 负载评分
        if () {
           // 过载惩罚
        }

        // 4. 分配评分
    }

运行策略

由于估分分配策略只能避免 某些情况下的最坏分配 ,而无法选择 尽可能优秀的分配
笔者尝试在 运行策略 上下手

考虑这样一种情况
假如在低楼层之间(如B1到F2)有大量低优先级乘客请求,高楼层间如(B4到F7)有大量高优先级乘客请求

在先前的运行策略中,电梯往返时,低优先级乘客会先占满了电梯,导致后续无论多高优先级乘客都无法再进入电梯

直到低楼层间的乘客请求处理完后,才会开始处理高优先级乘客

故而,笔者构思这样一种策略
当电梯满员时,一旦当前楼层存在同向优先级高于电梯中最低优先级的请求

将电梯中最低优先级的乘客踢出电梯,进入PassengersQueue

再将高优先级乘客接入电梯

此种运行策略可以保证,在所有请求的总运行路程不会延长的前提下
能够优先处理高优先级请求的情况
还能够避免某些情况下,过量的请求分配至某一电梯,导致运行时间过长的问题

不过也可能存在由于大量优先级差距小的请求频繁开关门切换导致的耗电量激增的问题

可以考虑为切换乘客的优先级差距设置一个阈值 增加存在有人上下电梯时才进行切换的判断

程序终止

由于本次作业新增了可以取消receive请求的Sche请求,以及电梯可以把乘客踢入PassengersQueue的功能
参考课上实验代码设计的终止判断
考虑以下情况

  • 在输入线程终止,调度线程终止时,电梯线程可能由于执行Sche请求或者将乘客踢入PassengersQueue,导致PassengersQueue不为空

  • 而此时调度线程已经终止,此时PassengersQueue中的请求无法再分配,无法再处理乘客请求

笔者选择,在Main类中新增static变量,类型设置为AtomicInteger,保证对变量操作的原子性
当InputThread接受到乘客请求时,该变量自增;当Elevator处理完乘客请求,该变量自减
直到该变量为0,Scheduler线程才终止

此种方法可以避免死锁,也算是一种取巧的办法

代码如下

private static final AtomicInteger number = new AtomicInteger(0);

    public static int getNumber() {
        return number.get();
    }

    public static void addNumber() {
        number.incrementAndGet();
    }

    public static void subNumber() {
        number.decrementAndGet();
    }

然而,由于此时Scheduler线程和Elevator线程互为生产消费者

此种设计会出现Scheduler线程的轮询,故而在Scheduler中加入sleep语句

第三次作业

本次作业新增UPDATE请求,将两部电梯合并为双轿厢电梯

双轿厢电梯的两个轿厢,仍然是电梯线程,其处理逻辑并未改变,故而
可以将轿厢看作更改了运行范围的初始电梯,同时增加了避免同时占据分隔目标楼层的要求
如此一来,修改接受Update请求的初始电梯的运行范围,便可以避免额外增减线程带来的额外开销,直接使用原电梯线程
同时无需对Scheduler进行修改,也无需新增ProcessingQueue对象

同步设计

为了UPDATE请求的两部电梯能够同时完成UPDATE请求,以及避免同时占据分隔目标楼层
可以在Elevator执行UPDATE请求时,在两部电梯中新增一个共用锁lock

架构设计如下

img

UPDATE同步完成的实现

Object lock = ...
synchronized (lock) {
            //更改状态为READY
            if (//当配对电梯READY) {
                //...
                //唤醒
            } else {
                //等待
            }

其逻辑如下

img

避免同时占据分隔目标楼层的实现

private void move() {
        if (//静止状态) {
           //如果占据分隔目标楼层则唤醒
            return;
        }
        // 检查下一层是否为当前电梯的分隔目标楼层
        if (//存在配对轿厢) {
            if (//下一层为分隔目标楼层) {
                Object lock = ...
                synchronized (lock) {
                    Integer occupiedBy = ...
                    if(//分隔目标楼层已被配对轿厢占用) {
                        if (//配对轿厢线程不为等待状态) {
                            //等待
                        }
                        if (//配对轿厢线程为等待状态) {
                            //配对轿厢移动
                        }
                    }
                   // 标记分隔层为当前轿厢占用
                }
            }
        }
        // 执行移动

        // 更新占用状态
    }

迭代变化

显著变化的点

  • Scheduler线程中的请求调度
  1. 三种请求的分配
  • Elevator线程中的请求执行
  1. 运行策略的变化
  2. 为满足Sche、Update请求对in、out、move等方法的修改

极少变化的点

除了以上两类,其他类几乎没有变化

多线程debug

由于6个Elevator线程本质上并没有不同
为了提高同样样例下多线程运行的压力,也为了更方便观察线程运行
我在Scheduler中将分配电梯强制划定为1、2
集中对其进行数据轰炸

然而,此种方式也有明显问题
在第三次作业中,由于我在测试时将分配电梯强制划定为1、2
并未发现将锁设置为分隔目标楼层,导致的一旦双轿厢电梯分隔楼层相同,就会出现双轿厢电梯共用一把锁,进而导致输出错误的bug

还是得完整测试,不能想当然(/(ㄒoㄒ)/~~)

心得体会

线程安全

  • 线程的run循环中需要注意避免轮询
  • 避免在线程类中直接加锁,尽量在非线程的共享类中加锁
  • 避免加多把锁,容易出现意料之外的问题

层次化设计

由于本次作业主要设计都是参考的课上实验代码,从第一次作业到第三次作业的架构并没有什么变化
好的层次化设计可以极大减少迭代时间,但是一旦想要使用其他性能优化方法(如影子电梯)就很难,需要修改非常多的地方

不过,由于大量修改都集中于Elevator类,导致其代码十分臃肿
在其他类只有寥寥数十行的时候,Elevator类以一己之力干到了将近500行,
其中存在大量的冗余代码,以及一些不优雅的判断语句
这大概也是我难以使用其他性能优化方法的原因吧(

...全文

相关推荐

弱电网下光伏并网逆变器序阻抗建模仿真复现扫频法【序阻抗判断稳定性】

内容概要:本文聚焦于弱电网条件下光伏并网逆变器的序阻抗建模与稳定性分析,系统阐述了基于扫频法的阻抗特性仿真与复现方法。通过构建正负序阻抗模型,深入剖析逆变器在弱电网环境中的动态响应特性,结合锁相环、电流环等关键控制环节对系统阻抗的影响机制,采用序阻抗稳定性判据评估多机并网或复杂电网条件下的系统稳定裕度。研究在Simulink平台中实现激励信号注入、频率响应采集与阻抗曲线绘制,为高比例新能源接入背景下并网系统的稳定性分析提供了可靠的仿真手段与理论支撑,尤其适用于SCI级别论文成果的复现与拓展验证。; 适合人群:电力电子、新能源并网技术及相关领域的硕士/博士研究生、科研人员,以及从事光伏逆变器、微电网稳定控制开发的工程技术人员。; 使用场景及目标:①掌握扫频法在电力电子装置阻抗建模中的具体实施流程;②理解并应用基于序阻抗的稳定性判据进行系统稳定边界分析;③用于高水平学术论文(如SCI期刊)中阻抗建模与稳定性分析部分的仿真复现与方法验证; 阅读建议:建议读者结合文中所述方法与提供的参考文献,自主搭建Simulink仿真模型,逐步完成扰动信号设计、数据采集、傅里叶分析及阻抗拟合全过程,深入探究控制参数变化对系统阻抗特性和稳定性的具体影响,强化理论与实践的融合能力。

欢多天天写代码

三相并网逆变器虚拟阻抗+统一有源阻尼策略SVPWM+SPWM调制仿真

内容概要:本文档系统性地介绍了三相并网逆变器的核心控制技术及其在复杂电网环境下的仿真应用,重点涵盖虚拟阻抗与统一有源阻尼策略在SVPWM和SPWM调制方式下的实现方法,旨在提升逆变器的稳定性与电能质量。内容包括无功功率扰动孤岛检测、中点电位平衡控制、低电压穿越(LVRT)、模型预测控制(MPC)、正负序分离、电网前馈控制等关键技术,并扩展至风储联合调频、微电网下垂控制、虚拟同步发电机(VSG)、构网型逆变器等多种典型电力系统应用场景。所有技术均配有基于Simulink/Matlab平台的完整仿真模型、参考文献及说明文档,强调理论分析与仿真实践的深度融合,突出科研中“借力”与创新思维的重要性。; 适合人群:电气工程、自动化、新能源等相关专业的研究生、科研人员及从事电力电子与可再生能源系统开发的工程师;具备MATLAB/Simulink仿真基础和电力系统专业知识的技术人员。; 使用场景及目标:①开展三相并网逆变器控制策略的研究与优化设计;②复现高水平学术论文中的控制算法;③完成毕业课题、科研项目或工程仿真验证;④掌握虚拟阻抗、有源阻尼、SVPWM/SPWM调制、MPC、VSG等核心技术的建模与实现方法;⑤支撑微电网、构网型变流器等前沿方向的科研攻关。; 阅读建议:建议按照资源目录结构化学习,优先选择与自身研究方向契合的内容模块,结合提供的仿真模型、参考文献和说明材料进行实操演练,注重从理论推导到仿真实现的全过程理解,充分利用共享网盘资源深化技术掌握,提升科研效率与创新能力。

欢多天天写代码

chromedriver-win32-159.0.8133.0(Canary).zip

chromedriver-win32-159.0.8133.0(Canary).zip

LCG元

计算机“101计划”《人工智能引论》教学大纲+课件+实训案例

计算机“101计划”《人工智能引论》教学大纲+课件+实训案例

qq_38220914

语音输入法离线语音输入转文字工具2.0支持双档本地识别模型,中英混说精准转写,纯离线运行保护隐私,让打字更高效.zip

大家好,我是大飞哥。日常打字时,频繁切换输入法、断网无法语音转写、或担心语音数据被传至云端,是许多办公族和内容创作者的共同痛点。这款离线语音输入工具 ,正是为此量身打造的 Windows 桌面语音辅助利器。它的核心使命就是按住快捷键说话,松开文字自动上屏,全程本地离线识别,让您在任何可输入文字的窗口内都能实现高效、私密的语音输入,彻底告别网络依赖与隐私焦虑。 在核心功能上,软件内置了两档本地语音识别模型,通过主界面下拉框即可随时切换。默认的“离线·标准”模式响应极快,支持中英混说且自带标点,非常适合日常聊天与文档撰写;而“离线·精准”模式则对纯中文、方言口音及长段落口述的识别准确度更高。更贴心的是,它具备实时预览与一键取消机制,说话过程中若发现说错,按下 Esc 即可取消,一个字都不会误输入;若目标窗口不支持直接写入,文字会自动存入剪贴板,方便您按 Ctrl+V 粘贴,确保每次发声都不白费。 这款工具在具体场景中的表现十分亮眼。对于办公白领,在填写表格、撰写邮件或使用微信、QQ 沟通时,无需频繁切换窗口,按住右键说话即可快速完成信息录入;对于程序员与文字工作者,在代码编辑器或文档中口述注释与段落,能显著提升创作效率;对于经常出差的商务人士,在飞机、高铁等断网环境下,它依然能稳定工作,不经过任何服务器,真正做到了“说了什么只有自己知道”,私密性极佳。 使用体验方面,软件将极简操作贯彻到底。解压后双击 大飞哥语音输入,右下角托盘出现蓝色话筒图标即代表准备就绪。用户只需将光标点进目标输入框,按住右 Alt说话,说完松开,文字便会自动写入。主界面提供了设置快捷键与开机自动启动选项,方便用户按习惯自定义组合键;关闭主窗口并不会退出程序,而是缩至托盘持续待命,彻底退出只需右键托盘或点击主界面按钮,逻辑清晰,零门槛上手。

大飞哥软件自习室
评论
收藏 已收藏
分享
返回顶部