1. 程式人生 > >Java模擬最短作業優先、時間片輪轉、最高響應比三種程序排程演算法

Java模擬最短作業優先、時間片輪轉、最高響應比三種程序排程演算法

本次試驗是使用程式來模擬作業系統中程序排程的三種不同的排程策略,分別為最短作業有限、時間片輪轉、最高響應比。

模擬的情況下,程序數為8,程序所需執行時間為隨機產生的整數,單位為1S,預設程序同時到達。

以下是實驗的程式碼:

Process.java是測試類,用於生成程序列表和測試三種不同的排程策略。

SJF.java是模擬實現最短作業優先的排程策略。

RR.java是模擬實現時間片輪轉的排程策略。

HRRN.java是模擬最高響應比的排程策略。

工程下載地址:

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