操作系统-进程调度算法

发布时间 2023-04-23 16:39:21作者: ran_ran

   具体功能需求:

   (1)数据初始化:数据初始化可通过键盘输入,也可通过构造函数直接生成相应对象。

   (2)算法选择功能:程序应向用户提供FCFS、SJ(P)F、优先权算法、时间片轮转算法的选项,由用户键盘输入选择算法,如:

      请输入要选择的算法:(0-FCFS; 1 -SJ(P)F; 2-优先权算法;3-时间片轮转算法 )

      当用户选择了优先权算法后,程序应能向用户提供是否为抢占的选项,如:

      请进一步选择(0-非抢占优先权算法;1-抢占优先权算法)

      当用户选择了时间片轮转算法后,应允许用户键盘输入时间片Q的大小,并根据服务时间的最大值给出相应提示,MAX为服务时间最大值:

      请进一步选择时间片大小:Q=1到MAX区间的整数

     当用户选择后,应输出:

     您选择了****算法,时间片为****,运行结果如下:

(3)输出格式:

    当用户选择了算法后,输出格式按照下图进行输出:

以下内容为个人作业回答,仅供参考,不保证正确率

源代码

MyProcess
 package report2.classes;

import java.util.Objects;

/**
 * Author:zouran
 * Date:2023/4/20  14:48
 * Description:数据结构
 */
public class MyProcess {
    //进程名字
    private String name;
    //到达时间
    private Integer arrival;
    //所需服务时间
    private Integer service;
    //权值,1为优先级最高
    private Integer weight;
    //进程开始作业时间
    private Integer start;
    //进程结束作业时间
    private Integer end;
    //当前进程以完成的作业时间
    private Integer current;
    //无参构造初始化进程
    public MyProcess() {
        this.current = 0;
        //时间片轮转使用
        this.end=0;
    }
    //格式化输出
    public void print(){
        System.out.printf("\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",name,arrival,service,start,end,getPeriod1(),getPeriod2());
    }
    //判断是否进程完成,service==current时代表完成
    public boolean isFinish() {
        return Objects.equals(service, current);
    }
    //计算周转周期
    public double getPeriod1() {
        return  (this.end - this.arrival);
    }
    //计算带权周转周期
    public double getPeriod2() {
        return (double) (this.end - this.arrival)/this.service;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getArrival() {
        return arrival;
    }

    public void setArrival(Integer arrival) {
        this.arrival = arrival;
    }

    public Integer getService() {
        return service;
    }

    public void setService(Integer service) {
        this.service = service;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public Integer getStart() {
        return start;
    }

    public void setStart(Integer start) {
        this.start = start;
    }

    public Integer getEnd() {
        return end;
    }

    public void setEnd(Integer end) {
        this.end = end;
    }

    public Integer getCurrent() {
        return current;
    }

    public void setCurrent(Integer current) {
        this.current = current;
    }
}
Calculate
 package report2.methods;

import report2.classes.MyProcess;

import java.util.*;

/**
 * Author:zouran
 * Date:2023/4/20  15:28
 * Description:进程方式
 */
public class Calculate {
    //记录当前全部进程
    private final List<MyProcess> myProcessList=new ArrayList<>();
    //记录进程输出顺序
    private final List<String> nameList=new ArrayList<>();
    //时间片队列
    LinkedList<MyProcess> myProcessQueue=new LinkedList<>();
    //记录当前时间,时间
    private Integer currentTime=0;
    //无参构造代替初始化
    public Calculate() {
        char[][] list = {
                {'A', '0', '4', '4'},
                {'B', '1', '3', '2'},
                {'C', '2', '5', '3'},
                {'D', '3', '2', '5'},
                {'E', '4', '4', '1'},};
        for (char[] chars : list) {
            MyProcess myProcess=new MyProcess();
            myProcess.setName(String.valueOf(chars[0]));
            myProcess.setArrival((int) chars[1]-48);
            myProcess.setService((int) chars[2]-48);
            myProcess.setWeight((int) chars[3]-48);
            this.myProcessList.add(myProcess);
        }
        //按到达时间排序
        myProcessList.sort(Comparator.comparing(MyProcess::getArrival));
    }
    //获取当前未完成的进程中最先到达进程,返回索引位置,返回-1代表进程全部结束
    public int findFirstIndex(){
        int index=-1,min=Integer.MAX_VALUE;
        for(int i=0;i<myProcessList.size();i++){
            //进程未完成且最先到
            if(!myProcessList.get(i).isFinish()
                    &&myProcessList.get(i).getArrival()<=min
                    &&myProcessList.get(i).getArrival()<=currentTime)
            {
                min=myProcessList.get(i).getArrival();
                index=i;
            }
        }
        return index;
    }
    //获取当前未完成的进程中最短作业进程,返回索引位置,返回-1代表进程全部结束
    public int findShortIndex(){
        int index=-1,min=Integer.MAX_VALUE;
        for(int i=0;i<myProcessList.size();i++){
            //进程未完成且最先到
            if(!myProcessList.get(i).isFinish()
                    &&myProcessList.get(i).getService()<=min
                    &&myProcessList.get(i).getArrival()<=currentTime)
            {
                min=myProcessList.get(i).getService();
                index=i;
            }
        }
        return index;
    }
    //原理同短作业进程
    public int findWeightIndex(){
        int index=-1,min=Integer.MAX_VALUE;
        for(int i=0;i<myProcessList.size();i++){
            //进程未完成且最先到
            if(!myProcessList.get(i).isFinish()
                    &&myProcessList.get(i).getWeight()<=min
                    &&myProcessList.get(i).getArrival()<=currentTime)
            {
                min=myProcessList.get(i).getWeight();
                index=i;
            }
        }
        return index;
    }
    //添加进程到进程队列
    public void findTimeIndex(Integer choice){
        for (MyProcess myProcess : myProcessList) {
            boolean isNotInQueue=true;
            //当前时间内到达的进程
            if(myProcess.getArrival()<=currentTime)
                //遍历进程队列
            {
                for (MyProcess process : myProcessQueue) {
                    //若存在,则标记为false
                    if (Objects.equals(myProcess.getName(), process.getName())) {
                        isNotInQueue = false;
                        break;
                    }
                }
                if (isNotInQueue) {
                    if(choice==1)
                     myProcessQueue.addFirst(myProcess);
                    else if(choice==2)
                        myProcessQueue.addLast(myProcess);
                }
            }
        }
    }
    //更新进程状态
    public void updateMyProcessList(MyProcess myProcess){
        for (MyProcess process : myProcessList) {
            if (Objects.equals(process.getName(), myProcess.getName())) {
                process.setStart(myProcess.getStart());
                process.setEnd(myProcess.getEnd());
                process.setCurrent(myProcess.getCurrent());
                break;
            }
        }
    }
    //非抢占式方法中进程运行参数的变化是一致的
    public void commonSearch(int index){
        //index=-1有俩种情况:1.所有作业完成(外层循环条件会判断) 2.存在时间段空作业
        if(index!=-1){
            int i=1;
            //设置进程开始使时间
            myProcessList.get(index).setStart(currentTime);
            while(i<=myProcessList.get(index).getService()){
                //记录进程
                nameList.add(myProcessList.get(index).getName());
                //更新当前时间
                currentTime++;
                //进程完成度+1
                myProcessList.get(index).setCurrent(myProcessList.get(index).getCurrent()+1);
                i++;
            }
            //记录结束时间
            myProcessList.get(index).setEnd(currentTime);
        }
        else {
            //当存在时间段空作业时
            currentTime++;
        }
    }
    //判断是否所有的进程已完成
    public boolean isNotAllFinished(){
        for (MyProcess myProcess : myProcessList) {
            if(!myProcess.isFinish()) return true;
        }
        return false;
    }
    //先来先到算法
    public void FCFS(){
        //循环结束条件为所有进程均完成
        while (isNotAllFinished()){
            //获取当前未完成的进程中最先到达进程
            int index=findFirstIndex();
            commonSearch(index);
        }
        print("FCFS");
    }
    //短进程优先算法
    public void SJPF(){
        while(isNotAllFinished()){
            int index=findShortIndex();
            commonSearch(index);
        }
        print("SJPF");
    }
    public void method3(){
        System.out.println("请进一步选择(0-非抢占优先权算法;1-抢占优先权算法)");
        Scanner scanner=new Scanner(System.in);
        int choice= scanner.nextInt();
        if(choice==0) method3_1();
        else if(choice==1) method3_2();
    }
    //0-非抢占优先权算法
    public void method3_1(){
        while(isNotAllFinished()){
            int index=findWeightIndex();
            commonSearch(index);
        }
        print("非抢占优先权算法");
    }
    //1-抢占优先权算法
    public void method3_2(){
        while(isNotAllFinished()){
            int index=findWeightIndex();
            //index=-1有俩种情况:1.所有作业完成(外层循环条件会判断) 2.存在时间段空作业
            if(index!=-1){
                //设置进程开始使时间
                   myProcessList.get(index).setStart(currentTime);
                    //记录进程
                    nameList.add(myProcessList.get(index).getName());
                    //更新当前时间
                    currentTime++;
                    //进程完成度+1
                    myProcessList.get(index).setCurrent(myProcessList.get(index).getCurrent()+1);
                //记录结束时间
                if(myProcessList.get(index).isFinish()) myProcessList.get(index).setEnd(currentTime);
            }
            else {
                //当存在时间段空作业时
                currentTime++;
            }
        }
        print("抢占优先权算法");
    }
    public void method4(){
        System.out.println("请进一步选择时间片大小:Q=1到3区间的整数");
        Scanner scanner=new Scanner(System.in);
        int week=scanner.nextInt();
        System.out.println("请进一步选择进程方式:0-新进程优先,1-老进程优先");
        int choice= scanner.nextInt();
        if(choice==0)
         method4_1(week,1);
        else if(choice==1)
        method4_1(week,2);
    }
    //时间片轮转算法
    public void method4_1(Integer week,Integer choice){
        while(isNotAllFinished()){
            findTimeIndex(choice);
            if(myProcessQueue.isEmpty())
                continue;
            MyProcess currentProcess=myProcessQueue.poll();
            //若进程未开始,设置进程开始使时间
            if(currentProcess.getCurrent()==0)
                currentProcess.setStart(currentTime);
            //周期week内进程未完成
            if(currentProcess.getService()-currentProcess.getCurrent()>=week)
            //进程完成度+week
            {
                //以每秒为单位记录进程
                for (int i = 1; i <= week; i++) {
                    nameList.add(currentProcess.getName());
                }
                //更新进程状态
                currentProcess.setCurrent(currentProcess.getCurrent() + week);
                //更新当前时间
                currentTime+=week;
            }
            else {
                //以每秒为单位记录进程
                for (int i = 1; i <= currentProcess.getService()-currentProcess.getCurrent(); i++) {
                    nameList.add(currentProcess.getName());
                }
                //更新当前时间
                currentTime+=currentProcess.getService()-currentProcess.getCurrent();
                //该周期内能完成进程,更新进程状态
                currentProcess.setCurrent(currentProcess.getService());
            }
            //记录结束时间
            if(currentProcess.isFinish()&&currentProcess.getEnd()==0) currentProcess.setEnd(currentTime);
            //未完成则加入队尾
            else myProcessQueue.add(currentProcess);
            //更新总进程队列中currentProcess对应进程信息
            updateMyProcessList(currentProcess);
        }
        if(choice==1)
         print("时间片轮转算法(新进程优先)");
        else if(choice==2) print("时间片轮转算法(老进程优先)");
    }
    //计算平均周转周期
    public double getAvgPeriod1(){
        double sum=0.0;
        for (MyProcess myProcess : myProcessList) {
            sum+=myProcess.getPeriod1();
        }
        return sum/myProcessList.size();
    }
    //计算平均带权周转周期
    public double getAvgPeriod2(){
        double sum=0.0;
        for (MyProcess myProcess : myProcessList) {
            sum+=myProcess.getPeriod2();
        }
        return sum/myProcessList.size();
    }
    //格式化输出
    public void print(String name){
        System.out.printf("\t\t\t\t%s\n",name);
        System.out.printf("\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n","进程名","到达时间","服务时间","开始时间","完成时间","周转时间","带权周转时间");
        for (MyProcess myProcess : myProcessList) {
            myProcess.print();
        }
        System.out.printf("\t%s\t\t\t\t\t%f\t%f\n","平均",getAvgPeriod1(),getAvgPeriod2());
        System.out.print("\t");
        for (String s : nameList) {
            System.out.print("["+s+"] ");
        }
        System.out.println();
    }
}
Main
 package report2;

import report2.methods.Calculate;

import java.util.Scanner;

/**
 * Author:zouran
 * Date:2023/4/20  14:47
 * Description:主程序
 */
public class Main {
    public static void main(String[] args){
        Scanner scanner=new Scanner(System.in);
        while(true){
            System.out.printf("\t\t\t%s\n","请输入要选择的算法:(0-FCFS; 1 -SJ(P)F; 2-优先权算法;3-时间片轮转算法;-1-退出 )");
            int choice= scanner.nextInt();
            if(choice==-1) break;
            Calculate calculate=new Calculate();
            switch (choice) {
                case 0 -> calculate.FCFS();
                case 1 -> calculate.SJPF();
                case 2 -> calculate.method3();
                case 3 -> calculate.method4();
            }
        }
    }
    
}
MyProcess类(用于记录每个进程信息)
  • 设置类的数据结构
  •   记录进程的名字、到达时间、开始时间、结束时间、要求的服务时间、当前已经服务的时间、优先级
    //进程名字
    private String name;
    //到达时间
    private Integer arrival;
    //所需服务时间
    private Integer service;
    //权值,1为优先级最高
    private Integer weight;
    //进程开始作业时间
    private Integer start;
    //进程结束作业时间
    private Integer end;
    //当前进程以完成的作业时间
    private Integer current;
  • 设置类的方法
  • 利用无参构造函数初始化,当前已服务时间为0,设置结束时间为0仅在时间片轮转处有用到
    //无参构造初始化进程
    public MyProcess() {
        this.current = 0;
        //时间片轮转使用
        this.end=0;
    }
  • 格式化输出当前进程
    //格式化输出
    public void print(){
        System.out.printf("\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",name,arrival,service,start,end,getPeriod1(),getPeriod2());
    }
  • 判断进程是否完成
    //判断是否进程完成,service==current时代表完成
    public boolean isFinish() {
        return Objects.equals(service, current);
    }
  • 计算周转周期
    //计算周转周期
    public double getPeriod1() {
        return  (this.end - this.arrival);
    }
  • 计算带权周转周期
    //计算带权周转周期
    public double getPeriod2() {
        return (double) (this.end - this.arrival)/this.service;
    }
  • 其他就是基本的set、get方法
set、get方法
     public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getArrival() {
        return arrival;
    }

    public void setArrival(Integer arrival) {
        this.arrival = arrival;
    }

    public Integer getService() {
        return service;
    }

    public void setService(Integer service) {
        this.service = service;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public Integer getStart() {
        return start;
    }

    public void setStart(Integer start) {
        this.start = start;
    }

    public Integer getEnd() {
        return end;
    }

    public void setEnd(Integer end) {
        this.end = end;
    }

    public Integer getCurrent() {
        return current;
    }

    public void setCurrent(Integer current) {
        this.current = current;
    }
Calculate类(包括四种进程方法)
  • 数据成员(要求记录所有进程、进程的服务顺序、当前时间、时间片轮转算法中要求使用队列)
    //记录当前全部进程
    private final List<MyProcess> myProcessList=new ArrayList<>();
    //记录进程输出顺序
    private final List<String> nameList=new ArrayList<>();
    //时间片队列
    LinkedList<MyProcess> myProcessQueue=new LinkedList<>();
    //记录当前时间,时间
    private Integer currentTime=0;
  • 方法
  • 无参构造函数进行初始化
    //无参构造代替初始化
    public Calculate() {
        char[][] list = {
                {'A', '0', '4', '4'},
                {'B', '1', '3', '2'},
                {'C', '2', '5', '3'},
                {'D', '3', '2', '5'},
                {'E', '4', '4', '1'},};
        for (char[] chars : list) {
            MyProcess myProcess=new MyProcess();
            myProcess.setName(String.valueOf(chars[0]));
            myProcess.setArrival((int) chars[1]-48);
            myProcess.setService((int) chars[2]-48);
            myProcess.setWeight((int) chars[3]-48);
            this.myProcessList.add(myProcess);
        }
        //按到达时间排序
        myProcessList.sort(Comparator.comparing(MyProcess::getArrival));
    }
  • 判断是否所有进程都已完成
    //判断是否所有的进程已完成
    public boolean isNotAllFinished(){
        for (MyProcess myProcess : myProcessList) {
            if(!myProcess.isFinish()) return true;
        }
        return false;
    }
  • 计算平均周期
    //计算平均周转周期
    public double getAvgPeriod1(){
        double sum=0.0;
        for (MyProcess myProcess : myProcessList) {
            sum+=myProcess.getPeriod1();
        }
        return sum/myProcessList.size();
    }
    //计算平均带权周转周期
    public double getAvgPeriod2(){
        double sum=0.0;
        for (MyProcess myProcess : myProcessList) {
            sum+=myProcess.getPeriod2();
        }
        return sum/myProcessList.size();
    }
  • 统一输出格式(传入的参数为算法名字)
    public void print(String name){
        System.out.printf("\t\t\t\t%s\n",name);
        System.out.printf("\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n","进程名","到达时间","服务时间","开始时间","完成时间","周转时间","带权周转时间");
        for (MyProcess myProcess : myProcessList) {
            myProcess.print();
        }
        System.out.printf("\t%s\t\t\t\t\t%f\t%f\n","平均",getAvgPeriod1(),getAvgPeriod2());
        System.out.print("\t");
        for (String s : nameList) {
            System.out.print("["+s+"] ");
        }
        System.out.println();
    }
  • 单个进程独立运行
       非抢占式方法中进程运行参数的变化是一致的,更新进程开始时间(start)为当前时间currentTime、结束时间(end)为currentTime+进程所需的服务时间service、
当前进程已完成的作业时间(current)为service,同时记录进程运行情况(每过一秒更新nameList)
    //非抢占式方法中进程运行参数的变化是一致的
    public void commonSearch(int index){
        //index=-1有俩种情况:1.所有作业完成(外层循环条件会判断) 2.存在时间段空作业
        if(index!=-1){
            int i=1;
            //设置进程开始使时间
            myProcessList.get(index).setStart(currentTime);
            while(i<=myProcessList.get(index).getService()){
                //记录进程
                nameList.add(myProcessList.get(index).getName());
                //更新当前时间
                currentTime++;
                //进程完成度+1
                myProcessList.get(index).setCurrent(myProcessList.get(index).getCurrent()+1);
                i++;
            }
            //记录结束时间
            myProcessList.get(index).setEnd(currentTime);
        }
        else {
            //当存在时间段空作业时
            currentTime++;
        }
    }
  • 先来先到算法

   在当前时间内的所有未完成的进程中找到最先到达的进程即可,找到即返回该进程在myProcessList中的索引位置index,否则返回-1

   返回-1有俩种情况

(1)当前时间内进程都已完成

(2)所有进程未完成,当前时间内存在空作业时间段(当前时间内能完成的进程都已完成,但后面存在进程)

    //获取当前未完成的进程中最先到达进程,返回索引位置,返回-1代表进程全部结束
    public int findFirstIndex(){
        int index=-1,min=Integer.MAX_VALUE;
        for(int i=0;i<myProcessList.size();i++){
            //进程未完成且最先到
            if(!myProcessList.get(i).isFinish()
                    &&myProcessList.get(i).getArrival()<=min
                    &&myProcessList.get(i).getArrival()<=currentTime)
            {
                min=myProcessList.get(i).getArrival();
                index=i;
            }
        }
        return index;
    }

最终实现,每次找到一个最先到达进程,直到所有进程完成

    public void FCFS(){
        //循环结束条件为所有进程均完成
        while (isNotAllFinished()){
            //获取当前未完成的进程中最先到达进程
            int index=findFirstIndex();
            commonSearch(index);
        }
        print("FCFS");
    }
  • 短进程优先算法

    原理同上,将找最先到达的进程条件改为找最短进程即可

    //获取当前未完成的进程中最短作业进程,返回索引位置,返回-1代表进程全部结束
    public int findShortIndex(){
        int index=-1,min=Integer.MAX_VALUE;
        for(int i=0;i<myProcessList.size();i++){
            //进程未完成且最先到
            if(!myProcessList.get(i).isFinish()
                    &&myProcessList.get(i).getService()<=min
                    &&myProcessList.get(i).getArrival()<=currentTime)
            {
                min=myProcessList.get(i).getService();
                index=i;
            }
        }
        return index;
    }

 最终实现

    //短进程优先算法
    public void SJPF(){
        while(isNotAllFinished()){
            int index=findShortIndex();
            commonSearch(index);
        }
        print("SJPF");
    }
  • 非抢占式优先权算法

   原理同上,将找最短进程条件改为优先级最高进程即可

    //原理同短作业进程
    public int findWeightIndex(){
        int index=-1,min=Integer.MAX_VALUE;
        for(int i=0;i<myProcessList.size();i++){
            //进程未完成且最先到
            if(!myProcessList.get(i).isFinish()
                    &&myProcessList.get(i).getWeight()<=min
                    &&myProcessList.get(i).getArrival()<=currentTime)
            {
                min=myProcessList.get(i).getWeight();
                index=i;
            }
        }
        return index;
    }

最终实现

    public void method3_1(){
        while(isNotAllFinished()){
            int index=findWeightIndex();
            commonSearch(index);
        }
        print("非抢占优先权算法");
    }
  • 抢占式优先权算法

     区别于前三种方法,前三种循环中每次循环都是进程为单位变化,当前进程完成后再找下一个进程

    抢占式算法要求每次循环以时间为单位,每经过一秒钟,便重新寻找下一个进程

    //1-抢占优先权算法
    public void method3_2(){
        while(isNotAllFinished()){
            int index=findWeightIndex();
            //index=-1有俩种情况:1.所有作业完成(外层循环条件会判断) 2.存在时间段空作业
            if(index!=-1){
                //设置进程开始使时间
                   myProcessList.get(index).setStart(currentTime);
                    //记录进程
                    nameList.add(myProcessList.get(index).getName());
                    //更新当前时间
                    currentTime++;
                    //进程完成度+1
                    myProcessList.get(index).setCurrent(myProcessList.get(index).getCurrent()+1);
                //记录结束时间
                if(myProcessList.get(index).isFinish()) myProcessList.get(index).setEnd(currentTime);
            }
            else {
                //当存在时间段空作业时
                currentTime++;
            }
        }
        print("抢占优先权算法");
    }
  • 时间片轮转算法(非抢占式)

总代码

时间片轮转算法
     //添加进程到进程队列
    public void findTimeIndex(Integer choice){
        for (MyProcess myProcess : myProcessList) {
            boolean isNotInQueue=true;
            //当前时间内到达的进程
            if(myProcess.getArrival()<=currentTime)
                //遍历进程队列
            {
                for (MyProcess process : myProcessQueue) {
                    //若存在,则标记为false
                    if (Objects.equals(myProcess.getName(), process.getName())) {
                        isNotInQueue = false;
                        break;
                    }
                }
                if (isNotInQueue) {
                    if(choice==1)
                     myProcessQueue.addFirst(myProcess);
                    else if(choice==2)
                        myProcessQueue.addLast(myProcess);
                }
            }
        }
    }
    //更新进程状态
    public void updateMyProcessList(MyProcess myProcess){
        for (MyProcess process : myProcessList) {
            if (Objects.equals(process.getName(), myProcess.getName())) {
                process.setStart(myProcess.getStart());
                process.setEnd(myProcess.getEnd());
                process.setCurrent(myProcess.getCurrent());
                break;
            }
        }
    }
    //时间片轮转算法
    public void method4_1(Integer week,Integer choice){
        while(isNotAllFinished()){
            findTimeIndex(choice);
            if(myProcessQueue.isEmpty())
                continue;
            MyProcess currentProcess=myProcessQueue.poll();
            //若进程未开始,设置进程开始使时间
            if(currentProcess.getCurrent()==0)
                currentProcess.setStart(currentTime);
            //周期week内进程未完成
            if(currentProcess.getService()-currentProcess.getCurrent()>=week)
            //进程完成度+week
            {
                //以每秒为单位记录进程
                for (int i = 1; i <= week; i++) {
                    nameList.add(currentProcess.getName());
                }
                //更新进程状态
                currentProcess.setCurrent(currentProcess.getCurrent() + week);
                //更新当前时间
                currentTime+=week;
            }
            else {
                //以每秒为单位记录进程
                for (int i = 1; i <= currentProcess.getService()-currentProcess.getCurrent(); i++) {
                    nameList.add(currentProcess.getName());
                }
                //更新当前时间
                currentTime+=currentProcess.getService()-currentProcess.getCurrent();
                //该周期内能完成进程,更新进程状态
                currentProcess.setCurrent(currentProcess.getService());
            }
            //记录结束时间
            if(currentProcess.isFinish()&&currentProcess.getEnd()==0) currentProcess.setEnd(currentTime);
            //未完成则加入队尾
            else myProcessQueue.add(currentProcess);
            //更新总进程队列中currentProcess对应进程信息
            updateMyProcessList(currentProcess);
        }
        if(choice==1)
         print("时间片轮转算法(新进程优先)");
        else if(choice==2) print("时间片轮转算法(老进程优先)");
    }

使用队列记录下一个进程进程轮转顺序,分为老进程优先和新进程优先俩种情况。

老进程优先则是在新进程和老进程同时到达时,在队列位置中,老进程在新进程前面,反之则为新进程优先

需要注意的是一个周期内进程已完成后时间有剩余的情况。

以下代码中,choice代表老进程或者新进程优先的选择,week代表时间片周转周期

大致思路如下,将当前时间内的进程都加入进程队列

    //添加进程到进程队列
    public void findTimeIndex(Integer choice){
        for (MyProcess myProcess : myProcessList) {
            boolean isNotInQueue=true;
            //当前时间内到达的进程
            if(myProcess.getArrival()<=currentTime)
                //遍历进程队列
            {
                for (MyProcess process : myProcessQueue) {
                    //若存在,则标记为false
                    if (Objects.equals(myProcess.getName(), process.getName())) {
                        isNotInQueue = false;
                        break;
                    }
                }
                if (isNotInQueue) {
                    if(choice==1)
                     myProcessQueue.addFirst(myProcess);
                    else if(choice==2)
                        myProcessQueue.addLast(myProcess);
                }
            }
        }
    }

判断队列是否为空,为空则表示空作业(若为进程全部完成,外层循环会结束)

            if(myProcessQueue.isEmpty())
                continue;

取队头元素,判断是否已经开始,否则将当前时间设置为其开始时间

            MyProcess currentProcess=myProcessQueue.poll();
            //若进程未开始,设置进程开始使时间
            if(currentProcess.getCurrent()==0)
                currentProcess.setStart(currentTime);

判断本次周期内能否完成,俩种情况

 //周期week内进程未完成
            if(currentProcess.getService()-currentProcess.getCurrent()>=week)
            //进程完成度+week
            {
                //以每秒为单位记录进程
                for (int i = 1; i <= week; i++) {
                    nameList.add(currentProcess.getName());
                }
                //更新进程状态
                currentProcess.setCurrent(currentProcess.getCurrent() + week);
                //更新当前时间
                currentTime+=week;
            }
            else {
                //以每秒为单位记录进程
                for (int i = 1; i <= currentProcess.getService()-currentProcess.getCurrent(); i++) {
                    nameList.add(currentProcess.getName());
                }
                //更新当前时间
                currentTime+=currentProcess.getService()-currentProcess.getCurrent();
                //该周期内能完成进程,更新进程状态
                currentProcess.setCurrent(currentProcess.getService());
            }

若本次周期内进程完成,记录进程结束时间,否则加入到队尾,更新总进程队列中本次进程currentProcess对应进程信息

            //记录结束时间
            if(currentProcess.isFinish()&&currentProcess.getEnd()==0) currentProcess.setEnd(currentTime);
            //未完成则加入队尾
            else myProcessQueue.add(currentProcess);
            //更新总进程队列中currentProcess对应进程信息
            updateMyProcessList(currentProcess);

上述updateMyProcessList()如下

    //更新进程状态
    public void updateMyProcessList(MyProcess myProcess){
        for (MyProcess process : myProcessList) {
            if (Objects.equals(process.getName(), myProcess.getName())) {
                process.setStart(myProcess.getStart());
                process.setEnd(myProcess.getEnd());
                process.setCurrent(myProcess.getCurrent());
                break;
            }
        }
    }