文章目录
- 实验内容:
实现的算法: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;
}
}