快速实现FCFS算法和SJF算法

该博客介绍了如何快速实现FCFS(先来先服务)和SPF(最短服务时间优先)两种作业调度算法。通过一个Java程序展示了这两种算法的流程,代码中使用了JCB实体类表示作业,并通过ProcessQueue类处理调度。在FCFS算法中,作业按到达时间排序,而SPF算法则按服务时间排序。程序的运行结果显示了两种算法的执行结果和相应的周转时间、带权周转时间的计算,对比了两种算法的效率。
摘要由CSDN通过智能技术生成

快速实现FCFS算法和SPF算法

先来看看代码的总体结构:

在这里插入图片描述

在如上图的流程中,FCFS算法和SJF算法唯一的区别就是中间步骤的排序方法不同。因此,只需要替换代码中的排序方法即可。

本程序中,默认是FCFS算法,如果需要SPF算法,可以将dequeue()方法中被注释的sortJcbsByServeTime()方法打开即可

代码中的注释相对详细,有因为是早些时候写的,所以某些地方设计的不是特别好,还请理解

代码

  • JCB实体类:

    package fcfs;
    
    import java.text.DecimalFormat;
    
    public class JCB {
        /**
         * 作业名
         */
        String name;
        /**
         * 到达时间
         */
        int arriveTime;
        /**
         * 服务时间
         */
        int serveTime;
        /**
         * 开始时间
         */
        int beginTime;
        /**
         * 结束时间
         */
        int finishTime;
        /**
         * 周转时间
         */
        int roundTime;
        /**
         * 带权周转时间
         */
        double aveRoundTime;
    
        public JCB() {
        }
    
        public JCB(String name, int arriveTime, int serveTime) {
            super();
            this.name = name;
            this.arriveTime = arriveTime;
            this.serveTime = serveTime;
        }
    
        @Override
        public String toString() {
            DecimalFormat df = new DecimalFormat("#0.00");
            return name + "\t\t"
                    + arriveTime + "\t\t"
                    + serveTime + "\t\t"
                    + beginTime + "\t\t"
                    + finishTime + "\t\t"
                    + roundTime + "\t\t"
                    + df.format(aveRoundTime);
        }
    }
    
  • ProcessQueue

    package fcfs;
    
    import java.text.DecimalFormat;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.LinkedList;
    
    public class ProcessQueue {
    
        //jcbs的下标
        int index = 0;
        //当前的时间
        private int currentTime = 0;
        //所有任务
        private ArrayList<JCB> jcbs;
        //就绪队列
        private LinkedList<JCB> ready = new LinkedList();
        //执行结束后的结果
        private ArrayList<JCB> result = new ArrayList<>();
        //平均周转时间
        private double avgRoundTime = 0;
        //周转时间和
        private double sumRoundTime = 0;
        //平均带权周转时间
        private double avgAveRoundTime = 0;
        //带权周转时间和
        private double sumAveRoundTime = 0;
    
        public ProcessQueue(ArrayList<JCB> jcbs) {
            this.jcbs = jcbs;
            //排序(如果是FCFS算法,则不能被注释)
            sortJcbs();
        }
    
        /**
         * 将要做的所有作业按照到达顺序进行排序
         */
        public void sortJcbs() {
            Collections.sort(jcbs,(o1, o2) -> {
                int time = o1.arriveTime - o2.arriveTime;
                if (time > 0) {
                    return 1;
                }else if (time == 0) {
                    //到达时间相同就比较服务时间
                    return o1.serveTime > o2.serveTime ? 1 : -1;
                }else {
                    return -1;
                }
            });
        }
    
        /**
         * 用于SJF算法
         * 对已到达的作业作业优先按照服务时间进行排序
         */
        public void sortJcbsByServeTime() {
            Collections.sort(ready,(o1, o2) -> {
                int time = o1.serveTime - o2.serveTime;
                if (time > 0) {
                    return 1;
                }else if (time == 0) {
                    //到达时间相同就比较服务时间
                    return o1.arriveTime > o2.arriveTime ? 1 : -1;
                }else {
                    return -1;
                }
            });
        }
    
    
        /**
         * 到达的作业进入就绪队列
         */
        public void enqueue() {
    
            while (index < jcbs.size()) {
                if (jcbs.get(index).arriveTime <= currentTime) {
                    //出队,index++,避免以及出队的进程重复出队
                    ready.add(jcbs.get(index));
                    index++;
                }else {
                    break;
                }
            }
    
        }
    
        /**
         * 第一个执行完的作业出队
         */
        public void dequeue() {
            if (!ready.isEmpty()) {
                //如果是(SJF算法,则下面这个方法不能被注释)
                //sortJcbsByServeTime();
                JCB jcb = ready.removeFirst();
                //设置出队列后的jcb的属性
                jcb.beginTime = currentTime;
                jcb.finishTime = jcb.beginTime + jcb.serveTime;
                jcb.roundTime = jcb.finishTime - jcb.arriveTime;
                jcb.aveRoundTime = (double) jcb.roundTime / jcb.serveTime;
                //重置当前时间
                currentTime = jcb.finishTime;
                //记录出队列的结果
                result.add(jcb);
            }
        }
    
        /**
         * 打印当前队列状况
         */
        public void showReady() {
    //        for (int i = 1; i < ready.size(); i++) {
    //            System.out.println("第" + i + "次队列情况:" + ready);
    //        }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("当前已到达的进程的情况:");
            ready.stream().forEach(r -> {
                stringBuilder.append(r.name + " ");
            });
            System.out.println(stringBuilder.toString());
        }
    
        /**
         * 执行程序
         */
        public void run() {
            //当有作业的时候就一直循环
            while (index < jcbs.size()) {
                //出队一个
                dequeue();
                //让到达的进程入队
                enqueue();
                //没有作业到达的时候,就等一下
                if (ready.isEmpty()) {
                    currentTime++;
                }
            }
            dequeue();
            dequeue();
            dequeue();
            System.out.println("++++++++++++++++++++++执++++++++行++++++++结++++++++果++++++++++++++++++");
            System.out.println("作业名" + "\t到达时间" + "\t服务时间" + "\t开始时间" + "\t完成时间" + "\t周转时间" + "\t带权周转时间");
            result.stream().forEach(s -> {
                sumRoundTime += s.roundTime;
                sumAveRoundTime += s.aveRoundTime;
                System.out.println(s);
            });
            DecimalFormat df = new DecimalFormat("#0.00");
            avgAveRoundTime = sumAveRoundTime/result.size();
            avgRoundTime = sumRoundTime/result.size();
            System.out.println("平均周转时间:" + df.format(avgRoundTime));
            System.out.println("平均带权周转时间 " + df.format(avgAveRoundTime));
        }
    
    }
    
  • Main函数:

    package fcfs;
    
    import java.util.ArrayList;
    
    public class Main {
        public static void main(String[] args) {
            //所有任务
            ArrayList<JCB> jcbs = new ArrayList<>();
            JCB p1 = new JCB("0", 3, 2);
            JCB p2 = new JCB("1", 1, 2);
            JCB p3 = new JCB("2", 5, 3);
            JCB p4 = new JCB("3", 7, 1);
            jcbs.add(p1);
            jcbs.add(p2);
            jcbs.add(p3);
            jcbs.add(p4);
            
            //将任务传入Fcfs程序中运行
            ProcessQueue process = new ProcessQueue(jcbs);
    
            process.run();
        }
    }
    

运行结果

SPF算法:

++++++++++++++++++++++执++++++++行++++++++结++++++++果++++++++++++++++++
作业名	到达时间	服务时间	开始时间	完成时间	周转时间	带权周转时间
1		1		2		1		3		2		1.00
0		3		2		3		5		2		1.00
2		5		3		5		8		3		1.00
3		7		1		8		9		2		2.00
平均周转时间:2.25
平均带权周转时间 1.25

FCFS算法:

++++++++++++++++++++++执++++++++行++++++++结++++++++果++++++++++++++++++
作业名	到达时间	服务时间	开始时间	完成时间	周转时间	带权周转时间
2		1		1		1		2		1		1.00
1		3		4		3		7		4		1.00
3		5		1		7		8		3		3.00
平均周转时间:2.67
平均带权周转时间 1.67

希望能帮助到大家^-^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

生命中有太多不确定

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

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

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

打赏作者

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

抵扣说明:

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

余额充值