短作业优先(SJF)调度算法(Java实现)


前言

在实现了先来先服务(FCFS)算法之后能够明显的感觉到先来先服务算法将当前处于就绪队列队首的那个进程调度到运行状态。也就是说,先来先服务算法只考虑作业或进程进入就绪队列的时间先后,而不考虑它的下一个CPU周期的长短等其他因素。虽然先来先服务算法简单易行并且是一种非抢占式策略,但性能却不大好导致平均周转时间特别长。因此,在先来先服务的算法基础上提出了短作业优先(SJF)算法来改进先来先服务算法,来减少平均周转时间。本文将介绍如何用Java来简单实现短作业优先调度算法


提示:以下是本篇文章正文内容,下面案例可供参考

代码实现

假设当前有四个进程先后到达系统进行调度:

作业名到达时间服务时间
A020
B515
C105
D1510

经过计算可得到如下结果:

作业名到达时间服务时间完成时间周转时间带权周转时间
A02020201
B51550453
C10525153
D151035202

平均周转时间: ( 20 + 15 + 20 + 45 ) / 4 = 25
平均带权周转时间:( 20 / 20 + 15 / 5 + 20 / 10 + 45 / 15 ) / 4 = 2.25

接下来编写Java程序,输出以上计算结果

1、作业类

代码如下(示例):

class ProcessData {
    // 到达时间
    public int arriveTime;
    // 服务时间
    public int serviceTime;
    // 完成时间
    public int finishTime;
    // 周转时间
    public int turnTime;
    // 带权周转时间
    public double powerTime;

    public ProcessData(int arriveTime, int serviceTime) {
        this.arriveTime = arriveTime;
        this.serviceTime = serviceTime;
    }

    @Override
    public String toString() {
        return arriveTime + "\t" +
                serviceTime + "\t" +
                finishTime + "\t" +
                turnTime + "\t" +
                powerTime;
    }
}

2、算法实现类

代码如下(示例):

public class ProcessProject {
    // 平均周转总时间
    public static double avgTotalTime;
    // 平均带权周转时间
    public static double avgPowerTime;

    public static void main(String[] args) {
        ProcessData[] processData = new ProcessData[4];

        // 定义四个作业
        processData[0] = new ProcessData(0, 20); // 作业A
        processData[1] = new ProcessData(5, 15); // 作业B
        processData[2] = new ProcessData(10, 5); // 作业C
        processData[3] = new ProcessData(15, 10); // 作业D
        // 短作业优先
        SJF(processData);
    }

    // 短作业优先算法
    private static void SJF(ProcessData[] processData) {
        int preFinished = 0; // 前一个作业的完成时间即下一个作业的开始时间
        avgTotalTime = 0;    // 平均周转时间
        avgPowerTime = 0;    // 平均带权周转时间

        for (int i = 0; i < processData.length; i++) {
            processData[i].finishTime = 0; // 设置完成时间为0
            processData[i].turnTime = 0; //周转时间
            processData[i].powerTime = 0; //平均周转时间
        }

        int number = 0;  // 定义作业号
        // 定义双层for循环用于比较作业的完成时间和服务时间
        for (int i = 0; i < processData.length; i++) {
            int min = 8888;
            for (int j = 0; j < processData.length; j++) {
                /**
                 *  1. 如果服务时间小于最小时间
                 *  2. 到达时间小于等于前一个作业的完成时间
                 *  3. 完成时间为0代表着还没有进行服务
                 *  最核心的地方就在于有完成时间限制着作业不会继续重复进入循环
                 */
                if (processData[j].serviceTime < min && processData[j].arriveTime <= preFinished && processData[j].finishTime == 0) {
                    min = processData[j].serviceTime; // 将目前服务时间最短的作业的服务时间赋值给作业的最小完成时间
                    number = j; // 将下一个进行调度的作业号赋值给number
                }
            }
            processData[number].finishTime = preFinished + processData[number].serviceTime;  // 当前作业的完成时间等于上一个作业的完成时间加当前作业的服务时间
            preFinished = processData[number].finishTime; // 将上一个作业的完成时间赋值为当前作业的完成时间
            processData[number].turnTime = processData[number].finishTime - processData[number].arriveTime;  // 周转时间 = 完成时间 - 到达时间
            processData[number].powerTime = processData[number].turnTime / processData[number].serviceTime;  // 带权周转时间 = 周转时间 / 服务时间
        }
        System.out.println("短进程优先算法:");
        Display(processData);
    }
	// 该方法用于将作业的各种信息进行打印
    private static void Display(ProcessData[] processData) {
        System.out.println("到达时间\t" + "服务时间\t" + "完成时间\t" + "周转时间\t" + "带权周转时间\t");
        for (int i = 0; i < processData.length; i++) {
            System.out.println(processData[i]);
            avgTotalTime += processData[i].turnTime; // 求总周转时间,此时avgTotalTime中存储的值为总周转时间
            avgPowerTime += processData[i].powerTime; // 求总带权周转时间,此时avgPowerTime中存储的值为总带权周转时间
        }

        avgTotalTime = avgTotalTime / processData.length; // 平均周转时间
        avgPowerTime = avgPowerTime / processData.length; // 平均带权周转时间

        System.out.println("平均周转时间:" + avgTotalTime);
        System.out.println("平均带权周转时间:" + avgPowerTime);
    }
}

3、运行结果

在这里插入图片描述


总结

以上便是短作业优先调度算法的Java实现,短作业优先算法的核心在于当系统中正在调度一个作业时,在当前作业调度完成之前到达系统的作业将会进行服务时间的比较,服务时间短的作业将在当前作业调度完成后优先进行调度。

  • 35
    点赞
  • 168
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dream_飞翔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值