Java模拟最短作业优先、时间片轮转、最高响应比三种进程调度算法

2021年9月7日 5点热度 0条评论 来源: 木子-勇士心

本次试验是使用程序来模拟操作系统中进程调度的三种不同的调度策略,分别为最短作业有限、时间片轮转、最高响应比。

模拟的情况下,进程数为8,进程所需执行时间为随机产生的整数,单位为1S,默认进程同时到达。

以下是实验的代码:

Process.java是测试类,用于生成进程列表和测试三种不同的调度策略。

SJF.java是模拟实现最短作业优先的调度策略。

RR.java是模拟实现时间片轮转的调度策略。

HRRN.java是模拟最高响应比的调度策略。

工程下载地址:

http://download.csdn.net/detail/qq_24369113/9711633

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 32706 on 2016/12/8.
 * 用于生成随机的进程列表,并测试三种不同的调度算法
 */
public class Process {

    public static List<double []> task_info=new ArrayList<>();//进程列表
    public static  int task_num=8;//进程数


    public static  void init_task()//初始化进程列表
    {
        for(int i=0;i<task_num;i++)
        {
            double[] t=new double[4];
            t[0]=i;//进程号
            t[1]=0;//到达时间
            t[2]=0;//响应比
            t[3]=(int)(Math.random()*100)%20+1;//需要运行时间
            task_info.add(t);
        }
    }

    public static void main(String arg[])
    {
        Process.init_task();//初始化进程列表


        System.out.println("最短作业优先================================================");
        SJF.init_task(task_info,task_num);
        SJF.SJF();//最短作业优先


        System.out.println("\n\n最高相应比================================================");
        HRRN.init_task(task_info,task_num);
        HRRN.HRRN();//高相应比


        System.out.println("\n\n时间片轮转================================================");
        RR.init_task(task_info,task_num);
        RR.CircleTime();//时间片轮转







    }
}

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by 32706 on 2016/12/8.
 * 最短时间优先算法
 */
public class SJF {

    private static int task_num = 8;
    public static List<double[]> task_time = new ArrayList<>();
    private static SimpleDateFormat df = new SimpleDateFormat("HHmmss");
    private static SimpleDateFormat tm = new SimpleDateFormat("HH:mm:ss");
    private static List<double[]> execute_time = new ArrayList<>();



    public static void SJF() {

        for (int i = 0; i < task_num; i++) {
            try {
                double[] t = get_task(task_time);
                int current_task_time = (int) t[3];
                int task_NO = (int) t[0];
                System.out.print(tm.format(new Date()) + "第" + task_NO + "号进程开始执行====");

                Thread.sleep(1000 * current_task_time);
                System.out.println("  " + tm.format(new Date()) + "执行完成=====用时为" + current_task_time + "S");


                double exe_time =System.currentTimeMillis() - t[1];
                double[] e = new double[2];
                e[0] = task_NO;
                e[1] = exe_time;
                execute_time.add(e);
            } catch (InterruptedException e) {
                e.printStackTrace();

            }

        }


       show_time();

    }


    public  static void show_time()
    {
        double sum_time=0;
        for(int i=0;i<execute_time.size();i++)
        {
            double[] t=execute_time.get(i);
            System.out.println("task:"+t[0]+":周转时间="+(int)(t[1]/1000)+"S");
            sum_time+=t[1];
        }
        System.out.println("使用最短作业优先的策略,平均周转时间为:"+(int)(sum_time/execute_time.size()/1000)+"S");
    }

    public static double[] get_task(List<double[]> task_time) {
        double[] rt = new double[4];
        double smallest_time = 50;

        int t = -1;
        for (int i = 0; i < task_time.size(); i++) {
            if (task_time.get(i)[3] < smallest_time) {
                smallest_time = task_time.get(i)[3];
                t = i;
            }
        }
        rt = task_time.get(t);
        task_time.remove(t);

        return rt;
    }

    static void init_task(List<double[]> task_info, int tn) {
        task_num = tn;
        for (int i = 0; i < task_num; i++) {
            double[] t = task_info.get(i);
            t[1] = System.currentTimeMillis();

            task_time.add(t);

        }
    }


}

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * Created by 32706 on 2016/12/8.
 * 时间片轮转调度算法
 */
public class RR {

    private  static SimpleDateFormat tm= new SimpleDateFormat("HH:mm:ss");
    private  static  int task_num=8;
    private  static  int Circle_size=4;//定义时间片大小
    public  static  ArrayBlockingQueue task_q=new ArrayBlockingQueue(task_num);//进程队列
    private  static  List<double[]> execute_time=new ArrayList<>();//进程执行时间

    public  static  void CircleTime()
    {
        try {
            while (true) {
                double[] t = new double[4];
                t = (double[])task_q.take();
                int current_task_time=(int)t[3];
                int task_NO=(int)t[0];
                System.out.print(tm.format(new Date())+"第" +task_NO+"号进程开始运行====");
                if(current_task_time<=Circle_size)//如果能够在本时间片中运行完成
                {
                    Thread.sleep((long) current_task_time*1000);//模拟运行所需时间
                    System.out.println(tm.format(new Date())+"结束执行=====本次用时"+current_task_time+"S");
                    double[] exe_t=new double[2];
                    exe_t[0]=task_NO;
                    exe_t[1]=System.currentTimeMillis()-t[1];//计算该进程所用的周转时间
                    execute_time.add(exe_t);//加入到周转时间队列
                }
                else {//如果不能再本次时间片中运行完
                    t[3]=t[3]-Circle_size;
                    task_q.put(t);
                    Thread.sleep(Circle_size*1000);
                    System.out.println(tm.format(new Date())+"本次时间片用完~~~~~进程等待");
                }


                if(task_q.size()==0)//如果进程队列为空了,就退出循环
                    break;


            }
        }
        catch (Exception e)
        {

        }
        show_time();//显示每个进程的调度时间

    }


    public static  void show_time()//显示每个进程的调度时间
    {
        double sum_time=0;
        for(int i=0;i<execute_time.size();i++)
        {
            double[] t=execute_time.get(i);
            System.out.println("task:"+t[0]+":周转时间="+(int)(t[1]/1000)+"S");
            sum_time+=t[1];
        }
        System.out.println("使用时间片轮转的策略,平均周转时间为:"+(int)(sum_time/execute_time.size()/1000)+"S");

    }

    static void init_task(List<double []> in,int tn)//初始化进程列表
    {
        task_num=tn;
        for(int i=0;i<task_num;i++)
        {
            double [] t=in.get(i);
            t[1] = System.currentTimeMillis();//获得进程到达时间
            try {
                task_q.put(t);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by 32706 on 2016/12/8.
 */
public class HRRN {
    private  static SimpleDateFormat tm= new SimpleDateFormat("HH:mm:ss");
    public  static List<double []> task_info=new ArrayList<>();//进程信息列表
    public static  int task_num=8;//进程数
    private static List<double[]> execute_time = new ArrayList<>();//进程周转时间列表


    public static  void HRRN(){

        for(int i=0;i<task_num;i++)
        {
            get_ratio();//每次循环时计算一次响应比
            double [] tem=get_a_task();//从进程列表中得到一个最高响应比的任务
            System.out.print(tm.format(new Date())+"第"+(int)tem[0]+"号进程开始运行====");
            try {
                Thread.sleep((long) tem[3]*1000);//模拟进程执行所需要的时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(tm.format(new Date())+"进程结束运行=====用时为"+(int)tem[3]+"S");
            double[] exe_t=new double[2];
            exe_t[0]=tem[0];
            exe_t[1]=System.currentTimeMillis() - tem[1];
            execute_time.add(exe_t);

        }

        show_time();//显示每个进程的周转时间

    }

    public  static void show_time()//显示每个进程的周转时间
    {
        double sum_time=0;
        for(int i=0;i<execute_time.size();i++)
        {
            double[] t=execute_time.get(i);
            System.out.println("task:"+t[0]+":周转时间="+(int)(t[1]/1000)+"S");
            sum_time+=t[1];
        }
        System.out.println("使用最高响应比的策略,平均周转时间为:"+(int)(sum_time/execute_time.size()/1000)+"S");

    }

   public static  double[] get_a_task()//根据响应比,返回一个最高相应比进程
   {
       double[]rt=new double[4];
       double max_ratio=0;
       int NO=-1;
       for(int i=0;i<task_info.size();i++)
       {
           if(task_info.get(i)[2]>max_ratio)
           {
               rt=task_info.get(i);
               max_ratio=task_info.get(i)[2];
               NO=i;
           }
       }
       task_info.remove(NO);//如果一个进程被选中,则在进程列表中删除掉
       return rt;


   }

    public static  void init_task(List<double[]> in,int tn)//初始化进程列表
    {
        task_num=tn;
        for(int i=0;i<in.size();i++)
        {
            double[] t=in.get(i);
            t[1]=System.currentTimeMillis();//获得进程到达时间
            task_info.add(t);
        }
    }

    public static  void  get_ratio()//计算每一个进程当前的响应比
    {
        for(int i=0;i<task_info.size();i++)
        {
            double[] t=task_info.get(i);
            task_info.remove(i);
            double ratio=(System.currentTimeMillis()-t[1])/t[3]+1;//计算响应比
            t[2]=ratio;
            task_info.add(t);

        }

    }



    public static void main(String arg[])//用于本类测试
    {
        Process.init_task();
        init_task(Process.task_info,Process.task_num);
        HRRN();
    }

}


实验结果如下所示:

"C:\Program Files\Java\jdk1.8.0_102\bin\java" -Didea.launcher.port=7534 "-Didea.launcher.bin.path=D:\软件\intellij idea\IntelliJ IDEA 2016.2.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_102\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\rt.jar;E:\java project\process scheduling\out\production\process scheduling;D:\软件\intellij idea\IntelliJ IDEA 2016.2.2\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain Process
最短作业优先================================================
11:50:19第1号进程开始执行====  11:50:22执行完成=====用时为3S
11:50:22第0号进程开始执行====  11:50:26执行完成=====用时为4S
11:50:26第3号进程开始执行====  11:50:34执行完成=====用时为8S
11:50:34第7号进程开始执行====  11:50:45执行完成=====用时为11S
11:50:45第2号进程开始执行====  11:50:59执行完成=====用时为14S
11:50:59第4号进程开始执行====  11:51:13执行完成=====用时为14S
11:51:13第5号进程开始执行====  11:51:31执行完成=====用时为18S
11:51:31第6号进程开始执行====  11:51:49执行完成=====用时为18S
task:1.0:周转时间=3S
task:0.0:周转时间=7S
task:3.0:周转时间=15S
task:7.0:周转时间=26S
task:2.0:周转时间=40S
task:4.0:周转时间=54S
task:5.0:周转时间=72S
task:6.0:周转时间=90S
使用最短作业优先的策略,平均周转时间为:38S


最高相应比================================================
11:51:49第2号进程开始运行====11:52:03进程结束运行=====用时为14S
11:52:03第1号进程开始运行====11:52:06进程结束运行=====用时为3S
11:52:06第0号进程开始运行====11:52:10进程结束运行=====用时为4S
11:52:10第3号进程开始运行====11:52:18进程结束运行=====用时为8S
11:52:18第7号进程开始运行====11:52:29进程结束运行=====用时为11S
11:52:29第4号进程开始运行====11:52:43进程结束运行=====用时为14S
11:52:43第5号进程开始运行====11:53:01进程结束运行=====用时为18S
11:53:01第6号进程开始运行====11:53:19进程结束运行=====用时为18S
task:2.0:周转时间=14S
task:1.0:周转时间=17S
task:0.0:周转时间=21S
task:3.0:周转时间=29S
task:7.0:周转时间=40S
task:4.0:周转时间=54S
task:5.0:周转时间=72S
task:6.0:周转时间=90S
使用最高响应比的策略,平均周转时间为:42S


时间片轮转================================================
11:53:19第0号进程开始运行====11:53:23结束执行=====本次用时4S
11:53:23第1号进程开始运行====11:53:26结束执行=====本次用时3S
11:53:26第2号进程开始运行====11:53:30本次时间片用完~~~~~进程等待
11:53:30第3号进程开始运行====11:53:34本次时间片用完~~~~~进程等待
11:53:34第4号进程开始运行====11:53:38本次时间片用完~~~~~进程等待
11:53:38第5号进程开始运行====11:53:42本次时间片用完~~~~~进程等待
11:53:42第6号进程开始运行====11:53:46本次时间片用完~~~~~进程等待
11:53:46第7号进程开始运行====11:53:50本次时间片用完~~~~~进程等待
11:53:50第2号进程开始运行====11:53:54本次时间片用完~~~~~进程等待
11:53:54第3号进程开始运行====11:53:58结束执行=====本次用时4S
11:53:58第4号进程开始运行====11:54:02本次时间片用完~~~~~进程等待
11:54:02第5号进程开始运行====11:54:06本次时间片用完~~~~~进程等待
11:54:06第6号进程开始运行====11:54:10本次时间片用完~~~~~进程等待
11:54:10第7号进程开始运行====11:54:14本次时间片用完~~~~~进程等待
11:54:14第2号进程开始运行====11:54:18本次时间片用完~~~~~进程等待
11:54:18第4号进程开始运行====11:54:22本次时间片用完~~~~~进程等待
11:54:22第5号进程开始运行====11:54:26本次时间片用完~~~~~进程等待
11:54:26第6号进程开始运行====11:54:30本次时间片用完~~~~~进程等待
11:54:30第7号进程开始运行====11:54:33结束执行=====本次用时3S
11:54:33第2号进程开始运行====11:54:35结束执行=====本次用时2S
11:54:35第4号进程开始运行====11:54:37结束执行=====本次用时2S
11:54:37第5号进程开始运行====11:54:41本次时间片用完~~~~~进程等待
11:54:41第6号进程开始运行====11:54:45本次时间片用完~~~~~进程等待
11:54:45第5号进程开始运行====11:54:47结束执行=====本次用时2S
11:54:47第6号进程开始运行====11:54:49结束执行=====本次用时2S
task:0.0:周转时间=4S
task:1.0:周转时间=7S
task:3.0:周转时间=39S
task:7.0:周转时间=74S
task:2.0:周转时间=76S
task:4.0:周转时间=78S
task:5.0:周转时间=88S
task:6.0:周转时间=90S
使用时间片轮转的策略,平均周转时间为:57S

Process finished with exit code 0


    原文作者:木子-勇士心
    原文地址: https://blog.csdn.net/qq_24369113/article/details/53537233
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。