多道批处理的两级调度模拟(Java/Swing/附源码/附可执行程序)

设计要求

题目

多道批处理系统的两级调度

要求概况

本课程设计要求模拟实现一个的多道批处理系统的两级调度。通过具体的作业调度、进程调度、内存分配等功能的实现,加深对多道批处理系统的两级调度模型和实现过程的理解。

具体要求

作业从进入系统到最后完成,要经历两级调度:作业调度和进程调度。作业调度是高级调度,它的主要功能是根据一定的算法,从输入井中选中若干个作业,分配必要的资源,如主存、外设等,为它们建立初始状态为就绪的作业进程。进程调度是低级调度,它的主要功能是根据一定的算法将CPU分派给就绪队列中的一个进程。
1. 假定某系统可供用户使用的主存空间共100KB,并有4台磁带机。主存分配采用可变分区分配方式且主存中信息不允许移动,对磁带机采用静态分配策略,作业调度分别采用最小作业优先算法,进程调度采用可抢占的最短进程优先算法。
2. 假定“预输入”程序已经把一批作业的信息存放在输入井了,并为它们建立了相应作业表。测试数据如下:

作业到达时间估计运行时间内存需要磁带机需要
JOB110:0025分钟15K2台
JOB210:2030分钟60K1台
JOB310:3010分钟50K3台
JOB410:3520分钟10K2台
JOB510:4015分钟30K2台

3. 分别在不同算法控制下运行设计的程序,依次显示被选中作业、内存空闲区和磁带机的情况。比较不同算法作业的选中次序及作业平均周转时间。

需求分析

从课程题目上进行分析,需要编写多道批处理的两级调度模拟器,其具备的功能有:在输入井中写入数据、设定相应的磁带机数量和内存块信息、用相应的调度算法进行作业和进程调度、显示运行全过程。
(1)输入作业:向输入井中预输入自定义作业,并验证作业的可执行性
(2)添加资源项:可向系统添加磁带机和内存块
(3)时间管理:显示当前时间,暂停和继续,设置一个单位的时间长度
(4)合并空间:可将所有的内存空间进行合并。
(5)选择算法:可以按照所需来调整调度算法
(6)动态显示数据:实时监控各个队列中的作业情况

系统设计

设计思想

使用java面向对象技术,对处理机、时间、作业、进程、输入井、后备队列、就绪队列、内存块、磁带机等“对象”都进行抽象化,用一个个“类”来模拟。
将上述的内容整合,让除处理机之外的类都能在处理机中相互协作或抑制,作业和进程的调度都要考虑内存块和磁带机的情况,并且能够对其进行更改数据。调度成功与否都会影响作业或进程所在的队列,以及各项资源数据。
系统编写一个时间类,时间的运走会触发两件事:进行执行或调度、更新显示内容。
使用Swing技术写界面,运用JFormDesigner工具进行拖动化设计。
时间类添加监听时间,监听时间的运行,检测到即更新swing界面显示内容。
以上实现模拟两级调度的过程。

模块层次图

在这里插入图片描述

模块解析

进程调度模块

在这里插入图片描述

作业调度模块

在这里插入图片描述

内存分配模块

在这里插入图片描述

时间管理模块

在这里插入图片描述

界面的设计

工具

JFormDesigner

界面外观

在这里插入图片描述

项目结构

在这里插入图片描述

关键代码

短进程优先
**
 * 进程执行一个时间单位
 */
private void SPF() {
    if (nowProess == null) {
        if (jobs2.size() != 0) {
            nowProess = jobs2.remove(0);
            nowProess.setStatus('R');
            System.out.println("时间:" + clock.getTime() + "|开始调用进程:" + nowProess.toString());
        } else if (integerJobHashMap.size() == 0 && well.size() == 0) {
            System.out.println("时间:" + clock.getTime() + "|任务完成");
            System.out.println("________________以下是结果_________");
            jobs3.sort(((o1, o2) ->o1.getID()-o2.getID()));
            for(int i=0;i<=jobs3.size()-1;i++){
                System.out.println(jobs3.get(i).toString());
            }
            run = false;
            return;
        } else {
            System.out.println("时间:" + clock.getTime() + "|无进程可调度");
            return;
        }
    }
    System.out.println("时间:" + clock.getTime() + "|正在执行:" + nowProess.toString());
    nowProess.setTime(nowProess.getTime() + 1);
    if (nowProess.getTime() == nowProess.getServiceTime()) {
        //已经执行完毕
        nowProess.setFinishTime(clock.getTime());
        nowProess.setRoundTime(nowProess.getFinishTime() - nowProess.getSubmitTime()+1);
        nowProess.setAveRoundTime((double) nowProess.getRoundTime() / nowProess.getServiceTime());
        nowProess.setStatus('F');
        System.out.println("时间:" + clock.getTime() + "|执行完毕:" + nowProess.toString());
        //释放空间的占用
        integerJobHashMap.remove(nowProess.getID());
        nowProess.setTapeGet(false);
        tapes += nowProess.getTapeNeeded();
        Block block = integerBlockHashMap.get(nowProess.getBlockID());
        Queue<Integer> queue = block.getJobIDs();
        queue.remove(nowProess.getID());
        block.setJobIDs(queue);
        block.setRemainSize(block.getRemainSize() + nowProess.getSize());
        integerBlockHashMap.put(block.getID(), block);
        for (int j = 0; j <= jobs1.size() - 1; j++) {
            if (jobs1.get(j).getID() == nowProess.getID()) {
                jobs1.remove(j);
            }
        }
        jobs3.add(nowProess);
        nowProess = null;
        BF();
    }
}
短作业优先
/**
 * 作业调度
 */
private void SJF() {
    if (jobs.size() == 0) {
        System.out.println("时间:" + clock.getTime() + ":无作业需要调度");
    }
    jobs.sort((o1, o2) -> o1.getServiceTime() - o2.getServiceTime());
    for (int i = 0; i <= jobs.size() - 1; i++) {
        nowJob = jobs.remove(0);
        jobs1.add(nowJob);
        //尝试分配
        integerJobHashMap.put(nowJob.getID(), nowJob);
        BF();
    }
    nowJob = null;
}
内存块分配BF算法
/**
 * 最佳适应
 */
public void BF() {
    if (integerJobHashMap.size() >= 1 && integerBlockHashMap.size() >= 1) {
        //按作业调度顺序来分配
        int jobID;
        for (int i = 0; i <= jobs1.size() - 1; i++) {
            jobID = jobs1.get(i).getID();
            if (integerJobHashMap.get(jobID) != null &&
                    integerJobHashMap.get(jobID).getState() == 0 &&
                    !integerJobHashMap.get(jobID).isTapeGet()) {
                JOB job = integerJobHashMap.get(jobID);
                System.out.println("时间:" + clock.getTime()+"选中作业:" + job.toString());
                //找到最佳适应的块
                int bestFitBlockID = -1;
                for (int blockID = 0; blockID <= integerBlockHashMap.size() - 1; blockID++) {
                    Block block = integerBlockHashMap.get(blockID);
                    if (block.getRemainSize() - job.getSize() >= 0) {
                        if (bestFitBlockID == -1) bestFitBlockID = blockID;
                        else if (block.getRemainSize() <= integerBlockHashMap.get(bestFitBlockID).getRemainSize()) {
                            bestFitBlockID = blockID;
                        }
                    }
                }
                //操作部分
                if (bestFitBlockID != -1 && job.getTapeNeeded() <= tapes) {
                    Block block;
                    block = integerBlockHashMap.get(bestFitBlockID);
                    block.setRemainSize(block.getRemainSize() - job.getSize());
                    block.addaJobID(jobID);
                    job.setState(1);
                    job.setBlockID(bestFitBlockID);
                    job.setTapeGet(true);
                    tapes -= job.getTapeNeeded();
                    integerBlockHashMap.put(bestFitBlockID, block);
                    integerJobHashMap.put(jobID, job);
                    System.out.println("时间:" + clock.getTime()+"作业分配成功:" + job.toString());
                    //抢占(排好队等待调度)
                    if(nowProess!=null && job.getServiceTime()< nowProess.getServiceTime()){
                        nowProess.setStatus('W');
                        jobs2.add(0,nowProess);
                        jobs2.add(0,job);
                        nowProess = null;
                        System.out.println("时间:" + clock.getTime()+"抢占成功"+job);
                    }else {
                        jobs2.add(job);
                        jobs2.sort((o1, o2) -> o1.getServiceTime()-o2.getServiceTime());
                    }
                } else {
                    System.out.println("时间:" + clock.getTime()+"作业分配失败:" + job.toString());
                    System.out.println("时间:" + clock.getTime()+"原因:空间不够或磁带不够");
                }
            }
        }
    }
}
内存块合并算法
**
 * 合并空间
 */
public void spaceToMerge() {
    if (integerBlockHashMap.size() > 0) {
        int size1 = integerBlockHashMap.size();
        for (int blockID = 0; blockID <= size1 - 1; blockID++) {
            if (integerBlockHashMap.get(blockID).getRemainSize() > 0) {
                int finalBlockID = blockID;
                while (finalBlockID < size1 - 1
                        && integerBlockHashMap.get(finalBlockID + 1).getRemainSize() == integerBlockHashMap.get(finalBlockID + 1).getSize()) {
                    finalBlockID++;
                }
                if (finalBlockID != blockID) {
                    int size = 0;
                    Block newBlock = new Block();
                    newBlock.setStartAddress(integerBlockHashMap.get(blockID).getEndAddress() - integerBlockHashMap.get(blockID).getRemainSize() + 1);
                    for (int startID = blockID; startID <= finalBlockID; startID++) {
                        Block block = integerBlockHashMap.get(startID);
                        size += block.getRemainSize();
                        block.setSize(block.getSize() - block.getRemainSize());
                        block.setRemainSize(0);
                        integerBlockHashMap.put(block.getID(), block);
                        if (startID == finalBlockID) {
                            newBlock.setSize(size);
                            newBlock.setRemainSize(size);
                        }
                    }
                    newBlock.setID(integerBlockHashMap.size());
                    newBlock.setEndAddress(newBlock.getStartAddress() + newBlock.getSize() - 1);
                    integerBlockHashMap.put(integerBlockHashMap.size(), newBlock);
                }
                blockID = finalBlockID;
            }
        }
    }
}

总结

对swing界面的刷新采用了响应式的设计,即在Clock时钟类中运用PropertyChangeSupport类,对每一次time的增加产生一定的行为。提升了程序执行的效率,也提升了数据呈现的精确度。
~
~
源码下载:https://download.csdn.net/download/GDUT_xin/12602118
点击进入下载页面

  • 5
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值