先来先服务(FCFS)的简单模拟实现(java)

目录

一、算法原理

 1.先来先服务(FCFS)

2.非抢占式短作业优先(SPF)

3.抢占式短作业优先(SJF)

4.高响应比优先调度算法(HRRN)

二、实验示例

三、具体代码

四、结果展示


一、算法原理

几种常用的调度算法原理

 1.先来先服务(FCFS)

       当作业调度采用该算法时,系统将按作业先后到达的次序来进行调度,或者说它是优先选择等待时间长的作业,将他们调入内存,而不管作业执行时间的长短,只有当该进程执行完或发生某事件而阻塞后,进程调度程序才将处理机分配给其它进程。

2.非抢占式短作业优先(SPF)

        以作业的长短来计算优先级,作业越短优先级越高,优先级越高的进程先执行,但是这种算法不是抢占式的,即如果有进程正在执行不能抢占处理机,而是要等进程执行完毕才能去调度优先级较高的进程先执行。

3.抢占式短作业优先(SJF)

       原理与SPF基本相同,但是不同的是SJF是抢占式的,即如果有一个进程的执行时间比当前正在执行的进程的剩余时间少的话就抢占当前的进程

4.高响应比优先调度算法(HRRN)

为每一个作业(进程)引入一个动态优先级,这个动态优先级随时间而增大,每当一个进程执行完毕或约到阻塞时就要通过这个算法计算出下一个要执行的作业

计算公式为:优先权=(等待时间+要求服务时间)/要求服务时间

二、实验示例

下面以FCFS为举例展示

  process

          Arrival Time       

           Brust Time

                    p1

                         0

                       3

                    p2

                         2

                        6

                    p3

                         4

                        4

                    p4

                         6

                         5

                    p5

                         8

                         2

分别计算出上表5个进程完成时间、周转时间、带权周转时间,并计算出平均周转时间和平均带权周转时间。

周转时间 = 完成时间 - 到达时间

带权周转时间 = 周转时间 / 完成一个进程需要的时间

三、具体代码


import java.util.Scanner;


public class ThreadDispatch {


    public static void FCFS(work[] works){
        System.out.println("先来先服务模拟开始。。。。");
        work w;
        for(int i = 0;i < works.length;i++){//按照冒泡排序按照到达时间进行升序排列
            for (int j = 0; j < works.length - i - 1; j++) {
                if(works[j].arrivalTime > works[j+1].arrivalTime){
                    w = works[j];
                    works[j] = works[j+1];
                    works[j+1] = w;
                }
            }
        }
        double totalTime = 0;//记录时间

        double[] turnTimes = new double[works.length];//记录每个进程的周转时间

        double[] weightTurnTimes = new double[works.length];//记录每个进程的带权周转时间

        for (int i = 0; i < works.length; i++) {

            System.out.println("当前时间: " + totalTime + ", " + works[i].processName + "开始运行" + "* * * * * *,运行时间为:" + works[i].burstTime);

            totalTime += works[i].burstTime;//完成时间

            double turnTime = totalTime-works[i].arrivalTime;//周转时间
            turnTimes[i] = turnTime; //记录每个进程的周转时间

            double weightTurnTime = turnTime/works[i].burstTime;//带权周转时间
            weightTurnTimes[i] = weightTurnTime;

            System.out.println("完成时间:" + totalTime + "\t周转时间:" + turnTime + "\t带权周转时间: " + weightTurnTime);
            System.out.println("\n");
        }

        double tempTurnTimes = 0; //为计算平均周转时间
        for (int i = 0; i < weightTurnTimes.length; i++) {
            tempTurnTimes += turnTimes[i];
        }

        double tempweightTurnTimes = 0; //为计算平均带权周转时间
        for (int i = 0; i < weightTurnTimes.length; i++) {
            tempweightTurnTimes += weightTurnTimes[i];
        }

        System.out.println("平均周转时间为:" + tempTurnTimes/works.length + ",平均带权周转时间为:" + tempweightTurnTimes/works.length);

    }

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        System.out.print("输入要执行的进程个数:");
        int n = scan.nextInt();
        work[] works = new work[n];

        System.out.println("请分别输入processName arrivalTime burstTime");
        for(int i = 0;i < n;i++){
            String name = scan.next();
            double time1 = scan.nextDouble();
            double time2 = scan.nextDouble();
            works[i] = new work(name,time1,time2);
        }
//        System.out.println("展示线程的信息:");
//        for(int i = 0;i<n;i++){
//            System.out.println(works[i].processName + " " + works[i].arrivalTime + " " + works[i].burstTime);
//        }
        FCFS(works);

    }
}
class work{
    String processName;  //进程名
    double arrivalTime; //一个作业或进程到达的时间
    double burstTime;   //进程执行需要的时间
    public work(String processName,double arrivalTime,double burstTime){
        this.arrivalTime = arrivalTime;
        this.burstTime = burstTime;
        this.processName = processName;
    }
}

四、结果展示

  • 10
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面分别介绍 FCFS、SSTF、SCAN 和 C-SCAN 磁盘调度算法Java 实现。 1. FCFS 磁盘调度算法 FCFS(First-Come, First-Served)磁盘调度算法是最简单的磁盘调度算法,它按照磁盘访问请求的提交顺序进行调度。 ```java import java.util.Scanner; public class FCFS { public static void main(String[] args) { // 输入磁盘访问序列 Scanner sc = new Scanner(System.in); System.out.print("请输入磁盘访问序列:"); String input = sc.nextLine(); String[] strArr = input.split(" "); int[] requestArr = new int[strArr.length]; for (int i = 0; i < strArr.length; i++) { requestArr[i] = Integer.parseInt(strArr[i]); } // 输入磁头起始位置 System.out.print("请输入磁头起始位置:"); int start = sc.nextInt(); // FCFS 算法 int total = 0; int currentPos = start; for (int i = 0; i < requestArr.length; i++) { int nextPos = requestArr[i]; total += Math.abs(nextPos - currentPos); currentPos = nextPos; } // 输出结果 System.out.println("磁头起始位置:" + start); System.out.println("磁盘访问序列:" + input); System.out.println("移动总距离:" + total); } } ``` 2. SSTF 磁盘调度算法 SSTF(Shortest Seek Time First)磁盘调度算法是按照磁头与下一个访问请求的距离来进行调度的。 ```java import java.util.Scanner; public class SSTF { public static void main(String[] args) { // 输入磁盘访问序列 Scanner sc = new Scanner(System.in); System.out.print("请输入磁盘访问序列:"); String input = sc.nextLine(); String[] strArr = input.split(" "); int[] requestArr = new int[strArr.length]; for (int i = 0; i < strArr.length; i++) { requestArr[i] = Integer.parseInt(strArr[i]); } // 输入磁头起始位置 System.out.print("请输入磁头起始位置:"); int start = sc.nextInt(); // SSTF 算法 int total = 0; int currentPos = start; int[] visited = new int[requestArr.length]; for (int i = 0; i < visited.length; i++) { visited[i] = 0; } for (int i = 0; i < requestArr.length; i++) { int minDist = Integer.MAX_VALUE; int nextPos = 0; for (int j = 0; j < requestArr.length; j++) { if (visited[j] == 0) { int dist = Math.abs(requestArr[j] - currentPos); if (dist < minDist) { minDist = dist; nextPos = requestArr[j]; } } } total += minDist; currentPos = nextPos; for (int j = 0; j < requestArr.length; j++) { if (visited[j] == 0 && requestArr[j] == currentPos) { visited[j] = 1; break; } } } // 输出结果 System.out.println("磁头起始位置:" + start); System.out.println("磁盘访问序列:" + input); System.out.println("移动总距离:" + total); } } ``` 3. SCAN 磁盘调度算法 SCAN 磁盘调度算法是按照磁头的移动方向扫描访问请求,到达磁盘末端后改变方向继续扫描。 ```java import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class SCAN { public static void main(String[] args) { // 输入磁盘访问序列 Scanner sc = new Scanner(System.in); System.out.print("请输入磁盘访问序列:"); String input = sc.nextLine(); String[] strArr = input.split(" "); int[] requestArr = new int[strArr.length]; for (int i = 0; i < strArr.length; i++) { requestArr[i] = Integer.parseInt(strArr[i]); } // 输入磁头起始位置 System.out.print("请输入磁头起始位置:"); int start = sc.nextInt(); // 输入磁盘大小 System.out.print("请输入磁盘大小:"); int size = sc.nextInt(); // 输入方向(0表示向外,1表示向内) System.out.print("请输入方向(0表示向外,1表示向内):"); int direction = sc.nextInt(); // SCAN 算法 int total = 0; int currentPos = start; int nextPos = 0; ArrayList<Integer> visited = new ArrayList<Integer>(); ArrayList<Integer> unvisited = new ArrayList<Integer>(); for (int i = 0; i < requestArr.length; i++) { if (requestArr[i] < currentPos) { visited.add(requestArr[i]); } else { unvisited.add(requestArr[i]); } } Collections.sort(visited); Collections.sort(unvisited); if (direction == 0) { for (int i = 0; i < unvisited.size(); i++) { nextPos = unvisited.get(i); total += Math.abs(nextPos - currentPos); currentPos = nextPos; } total += Math.abs(size - currentPos); currentPos = size; for (int i = visited.size() - 1; i >= 0; i--) { nextPos = visited.get(i); total += Math.abs(currentPos - nextPos); currentPos = nextPos; } } else { for (int i = visited.size() - 1; i >= 0; i--) { nextPos = visited.get(i); total += Math.abs(currentPos - nextPos); currentPos = nextPos; } total += currentPos; currentPos = 0; for (int i = 0; i < unvisited.size(); i++) { nextPos = unvisited.get(i); total += Math.abs(nextPos - currentPos); currentPos = nextPos; } } // 输出结果 System.out.println("磁头起始位置:" + start); System.out.println("磁盘访问序列:" + input); System.out.println("磁盘大小:" + size); System.out.println("方向:" + direction); System.out.println("移动总距离:" + total); } } ``` 4. C-SCAN 磁盘调度算法 C-SCAN(Circular SCAN)磁盘调度算法是 SCAN 算法的变体,它在 SCAN 算法的基础上将磁头到达磁盘末端后直接跳到磁盘起始位置,继续扫描。 ```java import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class CSCAN { public static void main(String[] args) { // 输入磁盘访问序列 Scanner sc = new Scanner(System.in); System.out.print("请输入磁盘访问序列:"); String input = sc.nextLine(); String[] strArr = input.split(" "); int[] requestArr = new int[strArr.length]; for (int i = 0; i < strArr.length; i++) { requestArr[i] = Integer.parseInt(strArr[i]); } // 输入磁头起始位置 System.out.print("请输入磁头起始位置:"); int start = sc.nextInt(); // 输入磁盘大小 System.out.print("请输入磁盘大小:"); int size = sc.nextInt(); // CSCAN 算法 int total = 0; int currentPos = start; int nextPos = 0; ArrayList<Integer> visited = new ArrayList<Integer>(); ArrayList<Integer> unvisited = new ArrayList<Integer>(); for (int i = 0; i < requestArr.length; i++) { if (requestArr[i] < currentPos) { visited.add(requestArr[i]); } else { unvisited.add(requestArr[i]); } } Collections.sort(visited); Collections.sort(unvisited); if (unvisited.size() > 0) { for (int i = 0; i < unvisited.size(); i++) { nextPos = unvisited.get(i); total += Math.abs(nextPos - currentPos); currentPos = nextPos; } total += Math.abs(size - currentPos); currentPos = 0; for (int i = 0; i < visited.size(); i++) { nextPos = visited.get(i); total += Math.abs(nextPos - currentPos); currentPos = nextPos; } } else { for (int i = visited.size() - 1; i >= 0; i--) { nextPos = visited.get(i); total += Math.abs(currentPos - nextPos); currentPos = nextPos; } } // 输出结果 System.out.println("磁头起始位置:" + start); System.out.println("磁盘访问序列:" + input); System.out.println("磁盘大小:" + size); System.out.println("移动总距离:" + total); } } ``` 以上就是 FCFS、SSTF、SCAN 和 C-SCAN 磁盘调度算法Java 实现,你可以根据需要选择相应的算法和代码进行实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值