文章目录


  • 实验内容:
    实现的算法:FCFS、SJF、HRRF
  • 程序功能:
    使用Java编写并调试一个模拟的进程调度程序,分别采用FCFS、SJF、HRRF调度算法进行调度,计算出开始时间、结束时间、周转时间、带权周转时间。并使用JavaGUI图形化。
  • 程序流程图:

    代码:
package Main;

import java.util.ArrayList;
import java.util.Vector;

import Utils.*;
import UI.*;

public class main {

    public static String flag = "";
    public static ArrayList<PCB> pcbArr = new ArrayList<PCB>();
    public static ArrayList<PCB> rArr = new ArrayList<PCB>();

    public static void main(String[] args) {
        new p_UI().setVisible(true);
    }

    public static void start() {

        if (flag == "先来先服务(FCFS)") {
            rArr = FCFS.FCFS(pcbArr);
        } else if (flag == "最短进程优先(SPF)") {
            rArr = SPF.SPF(pcbArr);
        } else if (flag == "响应比高者优先(HRN)") {
            rArr = HRN.HRN(pcbArr);
        }

        //刷新表格数据
        p_UI.data.clear();

        for (int i = 0; i < rArr.size(); i++) {
            Vector aData = new Vector();
            aData.add(rArr.get(i).id);
            aData.add(rArr.get(i).name);
            aData.add(rArr.get(i).priority);
            aData.add(rArr.get(i).workTime);
            aData.add(rArr.get(i).arriveTime);
            aData.add(rArr.get(i).beginTime);
            aData.add(rArr.get(i).finshTime);
            //计算周转时间和带权周转时间
            rArr.get(i).setTAT(rArr.get(i).getFinshTime() - rArr.get(i).getArriveTime());
            rArr.get(i).setWTAT(rArr.get(i).getTAT() / rArr.get(i).getWorkTime());
            aData.add(rArr.get(i).TAT);
            aData.add(rArr.get(i).WTAT);
            p_UI.data.add(aData);
        }

        //刷新表格
        p_UI.dtm.setDataVector(p_UI.data, p_UI.colName);
        p_UI.table.setModel(p_UI.dtm);
    }

    //撤销执行
    public static void revoke() {

        p_UI.tTAT.setText("");
        p_UI.tWTAT.setText("");
        p_UI.data.clear();

        for (int i = 0; i < pcbArr.size(); i++) {
            Vector aData = new Vector();
            aData.add(pcbArr.get(i).id);
            aData.add(pcbArr.get(i).name);
            aData.add(pcbArr.get(i).priority);
            aData.add(pcbArr.get(i).workTime);
            aData.add(pcbArr.get(i).arriveTime);
            p_UI.data.add(aData);
        }

        p_UI.dtm.setDataVector(p_UI.data, p_UI.colName);
        p_UI.table.setModel(p_UI.dtm);
    }
}
package Main;

public class PCB {
    public int id;            //序号
    public String name;        //进程名
    public int priority;       //优先级
    public double workTime;    //服务时间
    public double arriveTime;  //到达时间
    public double beginTime;   //开始运行时间
    public double finshTime;   //运行结束时间
    public double TAT;         //周转时间
    public double WTAT;        //带权周转时间

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public double getWorkTime() {
        return workTime;
    }

    public void setWorkTime(double workTime) {
        this.workTime = workTime;
    }

    public double getArriveTime() {
        return arriveTime;
    }

    public void setArriveTime(double arriveTime) {
        this.arriveTime = arriveTime;
    }

    public double getBeginTime() {
        return beginTime;
    }

    public void setBeginTime(double beginTime) {
        this.beginTime = beginTime;
    }

    public double getFinshTime() {
        return finshTime;
    }

    public void setFinshTime(double finshTime) {
        this.finshTime = finshTime;
    }

    public double getTAT() {
        return TAT;
    }

    public void setTAT(double tAT) {
        TAT = tAT;
    }

    public double getWTAT() {
        return WTAT;
    }

    public void setWTAT(double wTAT) {
        WTAT = wTAT;
    }

    public PCB() {
    }

    public PCB(int id, String name, double arrivetime, double workTime, int priority) {
        setId(id);
        setName(name);
        setArriveTime(arrivetime);
        setWorkTime(workTime);
        setPriority(priority);
    }
}
package UI;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

import Main.*;

public class p_UI extends JFrame {

    public static Vector data = new Vector(); //存放进程信息
    public static Vector colName = new Vector();
    public static DefaultTableModel dtm = new DefaultTableModel();
    public static JTable table = new JTable();
    public static JLabel tTAT = new JLabel("");
    public static JLabel tWTAT = new JLabel("");

    public p_UI() {

        super("进程调度模拟");

        int WIDTH = 720;
        int HEIGHT = 540;
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        this.setBounds((int) (screenSize.getWidth() - WIDTH) / 2, (int) (screenSize.getHeight() - HEIGHT) / 2, WIDTH, HEIGHT);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        init();
    }

    public void init() {

        JPanel P = new JPanel();
        P.setLayout(null);
        JScrollPane table = new JScrollPane(setTable());
        table.setBounds(3, 150, 700, 350);

        P.add(setPage());
        P.add(table);

        this.add(P);
    }

    //设置页面
    public JPanel setPage() {

        JPanel jp = new JPanel();
        jp.setBounds(0, 0, 700, 150);
        jp.setLayout(null);

        JLabel id = new JLabel("序号:");
        id.setBounds(10, 30, 40, 30);
        jp.add(id);

        JTextField idT = new JTextField();
        idT.setBounds(45, 30, 60, 30);
        jp.add(idT);

        JLabel name = new JLabel("进程名:");
        name.setBounds(115, 30, 60, 30);
        jp.add(name);

        JTextField nameT = new JTextField();
        nameT.setBounds(165, 30, 60, 30);
        jp.add(nameT);

        JLabel priority = new JLabel("优先级:");
        priority.setBounds(235, 30, 60, 30);
        jp.add(priority);

        JTextField priorityT = new JTextField();
        priorityT.setBounds(285, 30, 60, 30);
        jp.add(priorityT);

        JLabel workTime = new JLabel("服务时间:");
        workTime.setBounds(355, 30, 70, 30);
        jp.add(workTime);

        JTextField workTimeT = new JTextField();
        workTimeT.setBounds(415, 30, 60, 30);
        jp.add(workTimeT);

        JLabel arriveTime = new JLabel("到达时间:");
        arriveTime.setBounds(485, 30, 70, 30);
        jp.add(arriveTime);

        JTextField arriveTimeT = new JTextField();
        arriveTimeT.setBounds(545, 30, 60, 30);
        arriveTimeT.addKeyListener(new KeyAdapter() {
            @Override
            //enter 添加事件
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                if (e.getKeyChar() == KeyEvent.VK_ENTER) {
                    String id = idT.getText();
                    idT.setText("");
                    String name = nameT.getText();
                    nameT.setText("");
                    String priority = priorityT.getText();
                    priorityT.setText("");
                    String arriveTime = arriveTimeT.getText();
                    arriveTimeT.setText("");
                    String workTime = workTimeT.getText();
                    workTimeT.setText("");

                    //传递进程信息到main的执行程序
                    int idInt = Integer.parseInt(id);
                    int priorityInt = Integer.parseInt(priority);
                    double arriveTimeInt = Double.parseDouble(arriveTime);
                    double workTimeInt = Double.parseDouble(workTime);
                    main.pcbArr.add(new PCB(idInt, name, arriveTimeInt, workTimeInt, priorityInt));

                    //传递进程信息到表格显示
                    Vector aData = new Vector();//一行表格信息
                    aData.add(id);
                    aData.add(name);
                    aData.add(priority);
                    aData.add(workTime);
                    aData.add(arriveTime);
                    data.add(aData);
                    dtm.setDataVector(data, colName);
                    table.setModel(dtm);
                }
            }
        });
        jp.add(arriveTimeT);

        JButton add = new JButton("添加");
        add.setBounds(625, 30, 80, 30);
        add.setBackground(new Color(202, 204, 209));
        add.setBorderPainted(true);
        add.setFocusPainted(false);
        add.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                String id = idT.getText();
                idT.setText("");
                String name = nameT.getText();
                nameT.setText("");
                String priority = priorityT.getText();
                priorityT.setText("");
                String arriveTime = arriveTimeT.getText();
                arriveTimeT.setText("");
                String workTime = workTimeT.getText();
                workTimeT.setText("");

                //传递进程信息到main的执行程序
                int idInt = Integer.parseInt(id);
                int priorityInt = Integer.parseInt(priority);
                double arriveTimeInt = Double.parseDouble(arriveTime);
                double workTimeInt = Double.parseDouble(workTime);
                main.pcbArr.add(new PCB(idInt, name, arriveTimeInt, workTimeInt, priorityInt));

                //传递进程信息到表格显示
                Vector aData = new Vector();//一行表格信息
                aData.add(id);
                aData.add(name);
                aData.add(priority);
                aData.add(workTime);
                aData.add(arriveTime);
                data.add(aData);
                dtm.setDataVector(data, colName);
                table.setModel(dtm);
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
        jp.add(add);


        JLabel aTAT = new JLabel("平均周转时间:");
        aTAT.setBounds(10, 90, 100, 30);
        jp.add(aTAT);

        tTAT.setBounds(100, 90, 50, 30);
        jp.add(tTAT);

        JLabel aWTAT = new JLabel("平均带权周转时间:");
        aWTAT.setBounds(150, 90, 125, 30);
        jp.add(aWTAT);

        tWTAT.setBounds(265, 90, 50, 30);
        jp.add(tWTAT);

        JComboBox type = new JComboBox();
        type.addItem("先来先服务(FCFS)");
        type.addItem("最短进程优先(SPF)");
        type.addItem("响应比高者优先(HRN)");
        type.setBounds(360, 90, 180, 30);
        jp.add(type);

        JButton start = new JButton("执行");
        start.setBounds(555, 90, 70, 30);
        start.setBackground(new Color(202, 204, 209));
        start.setBorderPainted(true);
        start.setFocusPainted(false);
        start.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                main.flag = (String) type.getSelectedItem();
                main.start();
                double aveTAT = 0;
                double aveWTAT = 0;
                for (int i = 0; i < data.size(); i++) {
                    aveTAT += main.rArr.get(i).TAT;
                    aveWTAT += main.rArr.get(i).WTAT;
                }
                aveTAT /= data.size();
                aveWTAT /= data.size();
                tTAT.setText(String.valueOf(aveTAT));
                tWTAT.setText(String.valueOf(aveWTAT));
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
        jp.add(start);

        JButton back = new JButton("撤销");
        back.setBounds(625, 90, 70, 30);
        back.setBackground(new Color(202, 204, 209));
        back.setBorderPainted(true);
        back.setFocusPainted(false);
        back.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                main.revoke();
            }

            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseReleased(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
        jp.add(back);

        return jp;
    }

    //信息表格
    public JTable setTable() {

        colName.add("序号");
        colName.add("进程名");
        colName.add("优先级");
        colName.add("服务时间");
        colName.add("到达时间");
        colName.add("开始运行时间");
        colName.add("结束运行时间");
        colName.add("周转时间");
        colName.add("带权周转时间");

        //设置表格文字居中
        DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();
        tcr.setHorizontalAlignment(JLabel.CENTER);
        table.setDefaultRenderer(Object.class, tcr);

        dtm.setDataVector(data, colName);
        table.setModel(dtm);

        return table;
    }
}
package Utils;

import Main.PCB;
import java.util.ArrayList;
import java.util.Collections;

public class FCFS {

    //先来先服务算法(FCFS)
    public static ArrayList<PCB> FCFS(ArrayList<PCB> PCBArr) {

        //根据到达时间将输入队列排序,同时到达的进程根据序号排序
        for(int i=0;i<PCBArr.size();i++) {
            for(int j=i+1;j<PCBArr.size();j++) {
                if(PCBArr.get(i).getArriveTime()>PCBArr.get(j).getArriveTime()) {
                    Collections.swap(PCBArr, i, j);
                }
            }
        }

        //复制原PCB数组
        ArrayList<PCB> tempArr = PCBArr;
        //存储结果数组
        ArrayList<PCB> workArr = new ArrayList<PCB>();
        for(PCB p : tempArr) {
            if(workArr.size() == 0){    //执行第一个进程
                p.setBeginTime(p.getArriveTime());
                p.setFinshTime(p.getBeginTime()+p.getWorkTime());
            } else {
                p.setBeginTime(workArr.get(workArr.size()-1).getFinshTime());
                p.setFinshTime(p.getBeginTime()+p.getWorkTime());
            }
            workArr.add(p);
        }

        return workArr;
    }
}
package Utils;

import Main.PCB;

import java.util.ArrayList;

public class HRN {

    //响应比高者优先(HRN)算法,响应比 =(等待时间 + 工作时间)/ 工作时间
    public static ArrayList<PCB> HRN(ArrayList<PCB> PCBArr) {

        //由于刚开始多个进程如果同时第一个到达,其响应比都为1,所以不做判断,只根据到达时间获取第一个到达的进程
        PCB first;
        first = PCBArr.get(0);
        for (int i = 0; i < PCBArr.size(); i++) {
            if (first.getArriveTime() > PCBArr.get(i).getArriveTime()) {
                first = PCBArr.get(i);
            }
        }

        //复制原PCB数组
        ArrayList<PCB> tempArr = new ArrayList<PCB>();
        for (int i = 0; i < PCBArr.size(); i++) {
            tempArr.add(PCBArr.get(i));
        }

        //第一个进入工作队列中
        ArrayList<PCB> workArr = new ArrayList<PCB>();    //存储结果数组
        workArr.add(first);
        workArr.get(0).setBeginTime(first.getArriveTime());
        workArr.get(0).setFinshTime(first.getArriveTime() + first.getWorkTime());

        //删除已经进入工作队列的第一个进程的PCB
        tempArr.remove(first);

        //剩下的进程通过响应比高者优先调度算法依次进入工作队列
        while (!tempArr.isEmpty()) {
            ArrayList<PCB> temp = new ArrayList<PCB>();
            double lastFinshTime = workArr.get(workArr.size() - 1).getFinshTime();

            //筛选出在上一个进程结束前到达的进程放入temp数组
            for (PCB p : tempArr) {
                if (p.getArriveTime() < lastFinshTime) {
                    temp.add(p);
                }
            }

            if (temp.isEmpty()) {
                for (PCB p : tempArr)
                    temp.add(p);
            }

            //筛选出temp数组中响应比最高的进程first2
            PCB first2;
            first2 = temp.get(0);

            //记录当前first2指定进程的响应比
            double largeHrn = ((workArr.get(workArr.size() - 1).getFinshTime() - first2.getArriveTime()) + first2.getWorkTime()) / first2.getWorkTime();

            for (int i = 0; i < temp.size(); i++) {
                double hrn = ((workArr.get(workArr.size() - 1).getFinshTime() - temp.get(i).getArriveTime()) + temp.get(i).getWorkTime()) / temp.get(i).getWorkTime();
                if (largeHrn < hrn) {
                    largeHrn = hrn;
                    first2 = temp.get(i);
                }
            }

            //将first2对应进程放入工作队列并运行,同时在临时复制的PCB(tempArr)中删除该进程的PCB
            first2.setBeginTime(lastFinshTime);
            first2.setFinshTime(first2.getBeginTime() + first2.getWorkTime());
            workArr.add(first2);
            tempArr.remove(first2);
        }
        return workArr;
    }
}
package Utils;

import Main.PCB;

import java.util.ArrayList;

public class SPF {

    //最短进程优先算法(SPF)
    public static ArrayList<PCB> SPF(ArrayList<PCB> PCBArr) {

        //根据到达时间获取第一个到达并且服务时间较短的进程
        PCB first;
        first = PCBArr.get(0);
        for (int i = 0; i < PCBArr.size(); i++) {
            if (first.getArriveTime() == PCBArr.get(i).getArriveTime()) {
                if (first.getWorkTime() > PCBArr.get(i).getWorkTime()) {
                    first = PCBArr.get(i);
                }
            } else if (first.getArriveTime() > PCBArr.get(i).getArriveTime()) {
                first = PCBArr.get(i);
            }
        }

        //复制原PCB数组
        ArrayList<PCB> tempArr = new ArrayList<PCB>();
        for (int i = 0; i < PCBArr.size(); i++) {
            tempArr.add(PCBArr.get(i));
        }

        //第一个进入工作队列中
        ArrayList<PCB> workArr = new ArrayList<PCB>();  //存储结果数组
        workArr.add(first);
        workArr.get(0).setBeginTime(first.getArriveTime());
        workArr.get(0).setFinshTime(first.getArriveTime() + first.getWorkTime());

        //删除已经进入工作队列的第一个进程的PCB
        tempArr.remove(first);

        //剩下的进程通过最短进程优先调度算法依次进入工作队列
        while (!tempArr.isEmpty()) {
            ArrayList<PCB> temp = new ArrayList<PCB>();
            double lastFinshTime = workArr.get(workArr.size() - 1).getFinshTime();

            //筛选出在上一个进程结束前到达的进程放入temp数组
            for (PCB p : tempArr) {
                if (p.getArriveTime() < lastFinshTime) {
                    temp.add(p);
                }
            }

            if (temp.isEmpty()) {
                for (PCB p : tempArr)
                    temp.add(p);
            }

            //筛选出temp数组中最短的进程first2
            PCB first2;
            first2 = temp.get(0);
            for (int i = 0; i < temp.size(); i++) {
                if (first2.getWorkTime() > temp.get(i).getWorkTime())
                    first2 = temp.get(i);
            }

            //将first2对应进程放入工作队列并运行,同时在临时复制的PCB(tempArr)中删除该进程的PCB
            first2.setBeginTime(lastFinshTime);
            first2.setFinshTime(first2.getBeginTime() + first2.getWorkTime());
            workArr.add(first2);
            tempArr.remove(first2);
        }
        return workArr;
    }
}