Java 实现OS调度算法之短进程优先算法(SJF)

Posted _大木_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 实现OS调度算法之短进程优先算法(SJF)相关的知识,希望对你有一定的参考价值。

文章目录

短进程优先算法(SJF):shortest job first

算法描述:每次选出最短的进程进行调度,调度完毕则淘汰,直到所有进程都调度完毕。

思维导图:

例题: 对如下进程 使用SJF算法 进行排序和结果回显

正确结果:

施行SPF(非抢占式)算法:
   SPF的进程调度顺序为进程1、3、4、2,
   平均进程周转时间T = (20+15+20+45)/4 = 25
   平均带权进程周转时间W = (20/20+15/5+20/10+45/15)/4 = 2.25

Java实现:

package com.dhl.beyond.os_sjf;

import java.util.Scanner;

public class SJF 
    String name;
    double arrivetime;  //进程到达时间
    double servicetime;  // 进程执行时间长度(服务时间)
    double starttime; //进程开始执行时间
    double finishtime; //进程执行完成时间
    double zztime; //周转时间
    double dqzztime; //带权周转时间
    public SJF() 
    public SJF(String name, double arrivetime, double servicetime) 
        this.name = name;
        this.arrivetime = arrivetime;
        this.servicetime = servicetime;


    



    //主方法
    public static void main(String[] args) 
        Scanner scanner = new Scanner(System.in);
        System.out.println("===============短进程优先调度算法========================");
        System.out.println("输入进程数目: ");
        int num = scanner.nextInt();

        //创建进程数组对象
        SJF[] p = new SJF[num];
        System.out.println("请创建进程对象, 输入进程名称 到达时间 服务时间 <例如: p1 0 20>");
        for (int i= 0; i<p.length; i++)
            System.out.println("请输入进程:" +(i+1)+"的信息: ");
            p[i] = new SJF(scanner.next(), scanner.nextDouble(),scanner.nextDouble());
        
        OS_SJF(p); //调用短进程优先算法
        scanner.close();
    


    //短进程优先算法
    private static void OS_SJF(SJF[] p) 
        sort(p); //排序
        run(p); //执行该进程
        print(p); //显示界面

        double Attime=0 ,AQttime = 0;
        for (int k=0; k<p.length;k++)
            Attime += p[k].zztime;
            AQttime += p[k].dqzztime;
        
        Attime = Attime/p.length;
        AQttime = AQttime/p.length;

        System.out.println("调用短进程优先的平均周转时间为: "+Attime);
        //  System.out.printf("%.3f\\n",AQttime);
        System.out.println("调用短进程优先的平均带权周转时间为: "+AQttime);
    

    //排序算法(冒泡排序法)
    public static void sort(SJF[] p) 
        /************按照到达时间先进行排序**************/

        //  1.对SJF型数组中的元素进行一个简单的排序,找到优先级最高的进程,并且把其他进程进行简单排序,方便后续工作
        
        //冒泡排序:N次循环,每次找到从 i到n-1中优先级最好的进程,放到p[i]
        for (int i = 0; i < p.length; i++) 
            for (int j = i + 1; j < p.length; j++) 
                if (p[i].arrivetime > p[j].arrivetime) 
                    SJF temp;
                    temp = p[i];
                    p[i] = p[j];
                    p[j] = temp;
                
            
        
        // 2.每个进程运行完成之后,找到当前时刻已经到达的最短进程
        for (int m = 0; m < p.length; m++) 
            if (m == 0)  //p[0]的优先级最高
                p[m].finishtime = p[m].arrivetime + p[m].servicetime;
            else
                p[m].finishtime = p[m - 1].finishtime + p[m].servicetime;


            /********* 查找当前进程执行过程中进入系统的进程 ***********/
                    // 2.1 找到p[m].finishtime时刻哪些进程已经到达,从下一个进程p[m+1]开始寻找
            int i = 0;
            for (int n = m + 1; n < p.length; n++) 
                if (p[n].arrivetime <= p[m].finishtime) 
                    i++;
                
                   //2.2 找到p[m].finishtime时刻已经到达的最短进程
                int next = m + 1;
                double min = p[m + 1].servicetime; //next进程服务时间为p[m+1].servicetime
                //在 p[m+1]~p[m+i-1]这 i个已经到达的进程中找到最短进程
                for (int k = m + 2; k <= m + i; k++) 
                    if (p[k].servicetime < min) 
                        min = p[k].servicetime;
                        next = k;
						
				//2.3 把最短的进程 放在p[m+1]进程处
                SJF temp;
                temp = p[m + 1];
                p[m + 1] = p[next];
                p[next] = temp;
                    

                           
            
        
    

    //进程执行
    private static void run(SJF[] p) 
        for(int k=0; k<p.length;k++)
            if (k==0)
                p[k].starttime = p[k].arrivetime;
                p[k].finishtime = p[k].arrivetime+p[k].servicetime;
            else
                p[k].starttime = p[k-1].finishtime;
                p[k].finishtime = p[k-1].finishtime+p[k].servicetime;
            
        
        for (int k=0; k<p.length;k++)
            p[k].zztime = p[k].finishtime-p[k].arrivetime;  //计算该进程周转时间
            p[k].dqzztime=p[k].zztime/p[k].servicetime;  //计算该进程带权周转时间
        
    


    //结果回显
    private static void print(SJF[] p) 
        System.out.println("调用短进程优先算法后 进程运行的顺序是: ");
        System.out.println(p[0].name);
        for (int k=1;k<p.length;k++)
            System.out.print("-->"+p[k].name);
        
        System.out.println("");
        System.out.println("具体的调度信息: ");
        System.out.println("进程名  到达时间  服务时间   开始时间   结束时间   周转时间  带权周转时间");
        for(int k =0;k<p.length;k++)
            System.out.printf("%4s",p[k].name);
            System.out.printf("%10.3f",p[k].arrivetime);
            System.out.printf("%10.3f",p[k].servicetime);
            System.out.printf("%10.3f",p[k].starttime);
            System.out.printf("%10.3f",p[k].finishtime);
            System.out.printf("%10.3f",p[k].zztime);
            System.out.printf("%10.3f\\n",p[k].dqzztime);
        
    


测试结果

以上是关于Java 实现OS调度算法之短进程优先算法(SJF)的主要内容,如果未能解决你的问题,请参考以下文章

使用fcfs,sjf和rr调度算法,并判断哪个算法的平均等待时

进程调度算法1——FCFS、SJF、HNNR

操作系统| 作业调度算法平均周转时间平均带权周转时间先来先服务FCFS短作业优先SJF高优先权算法FPF高响应比优先算法HRRN

调度算法先来先服务(FCFS)最短作业优先(SJF)和最高响应比优先(HRRN)算法

作业调度算法平均周转时间平均带权周转时间先来先服务FCFS短作业优先SJF高优先权(级)算法FPF高响应比优先算法HRRN

FCFSSJFHRRN调度算法