一、实验目的

在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理机数时,就必须依照某种策略来决定哪些进程优先占用处理机。本实验模拟在单处理机情况下的进程调度,帮助学生加深了解进程调度的工作。

二、实验内容

设计一个按优先级调度算法实现进程调度的程序。
(实验代码为“抢占式优先级调度算法”)

三、系统分析与设计

1、数据结构

java 时间调度 java实现调度算法_算法

2、算法设计

java 时间调度 java实现调度算法_java_02

四、实现代码

进程控制块PCB类

public class PCB {
    //进程名:P1、P2、P3。。。
    private String name;
    //要求运行时间:1-5取随机数
    private int runTime;
    //优先级:1-10取随机数
    private int priorityNum;
    //进程状态:就绪W(Wait)、准备(Ready)或完成E(End)
    private String state ="R";
    //到达时间:1-5取随机数
    private int arrivalTime;

    //无参构造
    public PCB() {
    }

    //带五个参数的构造(进程名)
    public PCB(String name) {
        this.name = name;
        this.setRunTime(runTime);
        this.setPriorityNum(priorityNum);
        this.setState(state);
        this.setArrivalTime(arrivalTime);
    }

    //打印信息
    public void printInformation() {
        System.out.println(
            this.getName() + "\t\t"+this.getArrivalTime()+ "\t\t" + this.getRunTime() + "\t\t" +
            this.getPriorityNum() + "\t\t" + this.getState());
    }

    //PCB工作
    public void run() {
        this.priorityNum--;
        this.runTime-=DPS.CPUTIME;
    }

    public String getName() {
        return name;
    }

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

    public int getRunTime() {
        if(runTime<0){
            return 0;
        } else{
            return runTime;
        }
    }

    public void setRunTime(int runTime) {
        runTime = (int) (Math.random() * 5 + 1);
        this.runTime = runTime;
    }

    public int getPriorityNum() {return priorityNum;}

    public void setPriorityNum(int priorityNum) {
        priorityNum = (int) (Math.random()*10+1);
        this.priorityNum = priorityNum;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public int getArrivalTime() {
        return arrivalTime;
    }

    public void setArrivalTime(int arrivalTime) {
        arrivalTime = (int)(Math.random()*5+1);
        this.arrivalTime = arrivalTime;
    }
}

主函数:动态优先级调度算法Dynamic Priority Scheduling

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class DPS {
    public static final int CPUTIME = 2;//CPU时间片取固定值2

    public static void main(String[] args) throws InterruptedException {
        //一、初始化进程
        System.out.println("===========动态优先级调度算法=============");
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入进程数量:");
        int input = sc.nextInt();
        sc.close();
        Queue<PCB> queue = new LinkedList<PCB>();
        for (int i = 1; i <= input; i++) {
            queue.offer(new PCB("P" + i));
        }

        //二、进程入队并工作
        System.out.println("=======================================");
        System.out.println("名字\t" + "到达时间\t" + "要求运行时间\t" + "优先级数\t" + "状态");
        System.out.println("=======================================");

        ArrayList<PCB> sequence = new ArrayList<PCB>();

        while (!queue.isEmpty()) {
            //按照PCB优先级与到达时间排序
            if (queue.size() > 1) {
                getMax(queue);
            }
            if (!queue.isEmpty()) {
                //遍历队列,设置进程状态(增强For循环)
                for (PCB q : queue) {
                    if (q.equals(queue.peek())) {
                        //队首:进入工作状态
                        q.setState("W");
                    } else {
                        //非队首:进入就绪状态
                        if (q.getState().equals("W")) {
                            q.setState("R");
                        }
                    }
                    //打印信息
                    q.printInformation();
                }
                //进程运行
                queue.peek().run();
            }

            //若剩余运行时间小于等于0,进程状态转换为E(End)
            for (PCB q : queue) {
                if (q.getRunTime() <= 0) {
                    q.setState("E");
                }

                if (q.getState().equals("E")) {
                    System.out.println();
                    //打印信息
                    System.out.println("==============" + q.getName() + "进程结束================");
                    q.printInformation();
                    System.out.println("=======================================");
                    sequence.add(q);
                    queue.poll();
                    Thread.sleep(1500);
                    break;
                }
            }
            System.out.println();
        }
        //三、打印PCB完成顺序
        System.out.println("PCB结束工作的顺序为:");
        for (PCB q : sequence) {
            System.out.printf(q.getName() + "\t");
        }
    }

    //getMax()方法:找到最先抵达且优先级最高的PCB
    public static void getMax(Queue<PCB> queue) {
        int maxPriorityNum = 0;
        int minArrivalTime = 999;
        //找出最高优先级
        for (PCB q : queue) {
            if (q.getPriorityNum() > maxPriorityNum) {
                maxPriorityNum = q.getPriorityNum();
            }
        }
        //找出最高优先级中最早到达时间
        for (PCB q : queue) {
            if (q.getPriorityNum() == maxPriorityNum && q.getArrivalTime() < minArrivalTime) {
                minArrivalTime = q.getArrivalTime();
            }
        }

        PCB first = queue.peek();
        for (int i = 0; i < queue.size(); i++) {
            //将优先级最高的PCB移动到队首
            while (queue.peek().getPriorityNum() < maxPriorityNum) {
                queue.offer(queue.peek());
                queue.poll();
            }

            PCB q = ((LinkedList<PCB>) queue).get(i);//queue强转为LinkedList类型
            //跳过队首frist的判定
            if (!q.equals(first)) {
                //如果q的优先级等于队首优先级 且 到达时间比队首早
                if ((q.getPriorityNum() == queue.peek().getPriorityNum())
                        && q.getArrivalTime() < queue.peek().getArrivalTime()) {
                    //当队首到达时间不等于最早到达时间
                    while (queue.peek().getArrivalTime() != minArrivalTime) {
                        queue.offer(queue.peek());
                        queue.remove(queue.peek());
                        queue.remove(0);
                    }
                } else {
                    continue;
                }
            } else {
                continue;
            }
        }
    }
}