自己做的一个两种算法的进程调度模拟程序:
类ChooseMethordFrame:选择测试进程调度的算法窗口,也是程序的入口:
import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; public class ChooseMethordFrame extends JFrame implements ActionListener, ItemListener { private JComboBox methordBox; //选择调度算法的下拉列表 private JButton startButton; //开始测试按钮,进入另一个窗口 private String methordString; //保存用户选择的调度算法 // private JLabel jl = new JLabel(); public ChooseMethordFrame() { methordBox = new JComboBox(); methordBox.addItemListener(this); methordBox.addItem("高优先权调度算法"); methordBox.addItem("先到先服务调度算法"); startButton = new JButton("进入测试面板"); // startButton = new JButton(new ImageIcon("images/btn_play1.png")); // startButton.setRolloverIcon(new ImageIcon("images/btn_play2.png")); // startButton.setBorder(null); startButton.setToolTipText("进入测试面板"); startButton.addActionListener(this); //默认选择“高优先权调度算法” methordString = "高优先权调度算法"; this.setLayout(new GridLayout(2, 1)); JPanel jp1 = new JPanel(); jp1.add(methordBox); this.add(jp1); JPanel jp2 = new JPanel(); jp2.add(startButton); this.add(jp2); // this.add(jl); this.setSize(300, 200); Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); //将窗口置于屏幕中央 setLocation((scrSize.width - this.getSize().width) / 2, (scrSize.height - this.getSize().height) / 2); this.setResizable(false); this.setTitle("进程调度模拟"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == startButton) { this.setVisible(false); this.dispose(); Management management = new Management(methordString); Process.getManagement(management); new Thread(management).start(); } } //算法下拉列表的动作实现 public void itemStateChanged(ItemEvent ie) { if (methordBox.getSelectedIndex() == 0) { //选择高优先权调度算法 methordString = "高优先权调度算法"; } else if (methordBox.getSelectedIndex() == 1) { //选择的是先到先服务调度算法 methordString = "先到先服务调度算法"; } // jl.setText(methordString); } public static void main(String args[]) { new ChooseMethordFrame(); } }
类Management:进程调度的主要运行管理类
import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class Management extends JFrame implements ActionListener, Runnable{ private JTextArea showPaneArea; //显示进程调度的过程 private JButton startTestButton; //开始测试的按钮 private JTextField resourceField1; //第一个资源的输入框 private JTextField resourceField2; //第二个资源的输入框 private JTextField resourceField3; //第三个资源的输入框 private Process process; //进程 private int[] available; //系统资源 private JLabel remindLabel; //提示输入的label // private JLabel showResultLabel; //显示调度结果的label private String methordString; //算法选择字符串 //信息提示类 private RemindFrame remindFrame; public Management(String methordString) { this.methordString = methordString; remindFrame = new RemindFrame(); //设置信息对话框的主窗体 RemindFrame.setFatherFrame(this); showPaneArea = new JTextArea(); showPaneArea.setEditable(false); showPaneArea.setForeground(Color.white); showPaneArea.setBackground(Color.blue); // showPaneArea.setForeground(Color.red); startTestButton = new JButton("GO!");//, new ImageIcon("images/憨笑.gif")); // startTestButton.setBorder(null); startTestButton.setToolTipText("开始测试"); startTestButton.addActionListener(this); resourceField1 = new JTextField(5); resourceField2 = new JTextField(5); resourceField3 = new JTextField(5); remindLabel = new JLabel(""); remindLabel.setFont(new Font("宋体", Font.ITALIC | Font.BOLD, 16)); remindLabel.setForeground(Color.red); process = new Process(remindLabel, showPaneArea, resourceField1, resourceField2, resourceField3); this.setLayout(new BorderLayout()); // this.add(showResultLabel, BorderLayout.NORTH); this.add(new JScrollPane(showPaneArea), BorderLayout.CENTER); JPanel jp = new JPanel(); jp.add(remindLabel); jp.add(new JLabel("资源1")); jp.add(resourceField1); jp.add(new JLabel("资源2")); jp.add(resourceField2); jp.add(new JLabel("资源3")); jp.add(resourceField3); jp.add(startTestButton); this.add(jp, BorderLayout.SOUTH); this.setSize(600, 700); Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); //将窗口置于屏幕中央 setLocation((scrSize.width - this.getSize().width) / 2, (scrSize.height - this.getSize().height) / 2); this.setResizable(false); this.setTitle("进程调度模拟: " + this.methordString); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { //开始测试 if (e.getSource() == startTestButton) { synchronized (process) { //唤醒阻塞 process.notifyAll(); } } } //显示状态 private void showState() { //显示系统中可用资源 showPaneArea.append("\t系统中可用资源\n"); this.available = System.getSystemResource(); showPaneArea.append("资源1\t资源2\t资源3\t\n"); for (int i = 0; i < available.length; i++) { showPaneArea.append(available[i] + "\t"); } showPaneArea.append("\n\n"); //显示进程已得到资源情况 showPaneArea.append(process.getAllocationedInfo() + "\n"); //显示进程需要资源情况 showPaneArea.append(process.getProcessState() + "\n"); //显示就绪队列中的情况 showPaneArea.append(process.getArrangedQueState() + "\n"); //显示阻塞队列中的情况 showPaneArea.append(process.getBarrageQueState() + "\n"); } //选择算法 private void chooseMethord(){ if (methordString.equals("高度优先权调度算法")){ process.setHighWeight(); }else if (methordString.equals("先到先服务调度算法")){ process.setFCFS(); } } //程序主要运行区 public void run() { PCB tempPCB; // { // System.out.println("测试结束"); // } this.chooseMethord(); while (!process.isArrangedEmpty()) { //显示信息 this.showState(); //如果资源分配成功则返回分配资源的进程对象,否则返回null tempPCB = process.allocationResource(); //进程资源分配成功 if (tempPCB != null) { //修改进程的优先级 tempPCB.reducePrioNumber(); //修改进程运行时间 tempPCB.reduceRunTime(); //如果进程运行时间结束,则释放资源 if (tempPCB.getRunTime() == 0) { process.freeResource(tempPCB.getProcessId()); //从就绪队列中删除该进程 process.deleteProcess(tempPCB); //唤醒一个阻塞的进程 process.wakeUpProcess(); } } showPaneArea.append("-------------------------------------------------\t\t" + "-------------------------------------------\n"); }//while if (process.getBarrageNum() == 0) { showPaneArea.append("\n\t\t进程顺利执行完毕"); remindFrame.showRemindInfo("进程顺利执行完毕", "调度结束"); } else { showPaneArea.append("\t阻塞队列中还有" + process.getBarrageNum() + "个进程不能被执行"); remindFrame.showRemindInfo("阻塞队列中还有" + process.getBarrageNum() + "个进程不能被执行", "调度结束"); } } }
类PCB:进程的pcb,包含进程的必要信息
private int runTime; //进程还需要运行时间 private int arriveTime; //进程到达时间 private int prioNumber; //进程优先数 private int id; //进程id号 private String name; //进程名 //private boolean isOver; //进程是否结束的标志变量(true:结束;false:就绪) //初始化进程pcb public PCB(int runTime, int arriveTime, int prioNumber, int id, String name) { this.runTime = runTime; this.arriveTime = arriveTime; this.prioNumber = prioNumber; this.id = id; this.name = name; //this.isOver = false; //进程就绪 } //取得进程id public int getProcessId() { return this.id; } //取得进程运行时间 public int getRunTime() { return this.runTime; } //将进程运行时间减少1 public void reduceRunTime() { this.runTime--; } //取得进程到达时间 public int getArriveTime() { return this.arriveTime; } //取得进程优先级 public int getPrioNumber() { return this.prioNumber; } //让进程优先级降低1 public void reducePrioNumber() { if (this.prioNumber > 0) { this.prioNumber--; } } //取得进程名 public String getProcessName() { return this.name; } }
类Process:进程类,包含进程的资源处理方法等
import java.util.Iterator; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class Process { //各个进程需要的最大资源数 private int[][] max = new int[][]{{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}}; //各个进程已经分配的资源数 private int[][] allocation = new int[][]{{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}}; //各个进程还需要的资源数 private int[][] need = new int[][]{{7, 4, 3}, {1, 2, 2}, {6, 0, 0}, {0, 1, 1}, {4, 3, 1}}; //进程申请资源 手动输入 private int[] request = new int[]{0, 0, 0}; //工作向量 private int[] work = new int[]{0, 0, 0}; //表示是否完成 private int[] finish = new int[]{0, 0, 0, 0, 0}; //进程就绪队列 private ArrayList<PCB> arrangedQue; //进程阻塞队列 private ArrayList<PCB> barrageQue; //银行家安全性检查 private BankerSafetyCheck safetyChecker; //系统中可用资源 private int[] available; //调度算法 private DispatchMethord disMethord; //显示提示信息的label private JLabel remindLabel; //显示调度结果的label // private JTextArea showPaneArea; //输入请求资源的文件域 private JTextField resourceField1; private JTextField resourceField2; private JTextField resourceField3; //进程数 private int processNum; //主工作窗体的引用 private static Management management; public Process(JLabel remindLabel, JTextArea showPaneArea, JTextField resourceField1, JTextField resourceField2, JTextField resourceField3) { this.remindLabel = remindLabel; // this.showPaneArea = showPaneArea; this.resourceField1 = resourceField1; this.resourceField2 = resourceField2; this.resourceField3 = resourceField3; //默认为高优先权调度算法 disMethord = new HighWeight(); arrangedQue = new ArrayList<PCB>(); barrageQue = new ArrayList<PCB>(); this.available = System.getSystemResource(); safetyChecker = new BankerSafetyCheck(work, finish, request, available, need, allocation, arrangedQue, barrageQue, showPaneArea, processNum); Random rnd = new Random(); //产生5个1-10的随机数用于优先数 int a1 = rnd.nextInt(10) + 1; int a2 = rnd.nextInt(10) + 1; int a3 = rnd.nextInt(10) + 1; int a4 = rnd.nextInt(10) + 1; int a5 = rnd.nextInt(10) + 1; //产生5个1-5的随机数用于运行时间 int t1 = rnd.nextInt(5) + 1; int t2 = rnd.nextInt(5) + 1; int t3 = rnd.nextInt(5) + 1; int t4 = rnd.nextInt(5) + 1; int t5 = rnd.nextInt(5) + 1; //创建5个进程 PCB p0 = new PCB(t1, 0, a1, 0, "p0"); PCB p1 = new PCB(t2, 1, a2, 1, "p1"); PCB p2 = new PCB(t3, 10, a3, 2, "p2"); PCB p3 = new PCB(t4, 20, a4, 3, "p3"); PCB p4 = new PCB(t5, 30, a5, 4, "p4"); //将进程添加到就绪队列中 arrangedQue.add(p0); arrangedQue.add(p1); arrangedQue.add(p2); arrangedQue.add(p3); arrangedQue.add(p4); this.processNum = arrangedQue.size(); } public static void getManagement(Management management) { Process.management = management; } //判断就绪队列是否为空 public boolean isArrangedEmpty() { if (arrangedQue.isEmpty()) { return true; } else { return false; } } //得到阻塞队列中的进程数 public int getBarrageNum() { return barrageQue.size(); } //取得就绪队列中的进程需要资源的情况(need数组) public String getProcessState() { String str = "\t进程需要资源\n"; str += "进程id\t资源1\t资源2\t资源3\n"; for (int i = 0; i < need.length; i++) { str += i + "\t"; for (int j = 0; j < need[i].length; j++) { str += need[i][j] + "\t"; } str += "\n"; } return str; } //取得就绪队列中的进程(arrangedQue数组) public String getArrangedQueState() { PCB temp; String str = "\t就绪队列中的情况\n"; str += "进程id\t进程名\t进程优先级\t进程到达时间\t进程还需要运行时间\n"; Iterator<PCB> itr = arrangedQue.iterator(); while (itr.hasNext()) { temp = itr.next(); str += temp.getProcessId() + "\t" + temp.getProcessName() + "\t" + temp.getPrioNumber() + "\t" + temp.getArriveTime() + "\t" + temp.getRunTime() + "\n"; } return str; } //取得阻塞队列中的进程(barrageQue数组) public String getBarrageQueState() { String str = ""; if (barrageQue.isEmpty()) { str = "\t阻塞队列为空\n"; } else { Iterator<PCB> itr = barrageQue.iterator(); str = "\t阻塞队列中的情况\n"; str += "进程id\t进程名\t进程优先级\t进程到达时间\t进程还需要运行时间\n"; while (itr.hasNext()) { PCB temp = itr.next(); str += "" + temp.getProcessId() + "\t" + temp.getProcessName() + "\t" + temp.getPrioNumber() + "\t" + temp.getArriveTime() + "\t" + temp.getRunTime() + "\n"; } } return str; } //取得各个进程已经分配资源的信息 public String getAllocationedInfo() { String str = "\t进程已经分配的资源\n"; str += "进程id\t资源1\t资源2\t资源3\n"; for (int i = 0; i < allocation.length; i++) { str += i + "\t"; for (int j = 0; j < allocation[i].length; j++) { str += allocation[i][j] + "\t"; } str += "\n"; } return str; } //初始化高优先权调度算法 public void setHighWeight() { disMethord = new HighWeight(); } //初始化先到先服务算法 public void setFCFS() { disMethord = new FCFS(); } //分配资源 public PCB allocationResource() { boolean loopFlag = true; //根据不同的调度算法取得进程的id号 int processId = disMethord.getSuitId(arrangedQue); //提示输入申请资源的信息 this.remindLabel.setText("申请资源的进程id:" + processId + " :"); while (loopFlag) { try { synchronized (this) { this.wait(); } } catch (InterruptedException ex) { Logger.getLogger(Process.class.getName()).log(Level.SEVERE, null, ex); } if (this.checkInput()) { loopFlag = false; } else { JOptionPane.showMessageDialog(Process.management, "请输入大于或等于零的数字", "输入非法信息", JOptionPane.WARNING_MESSAGE); } } request[0] = Integer.parseInt(this.resourceField1.getText().trim()); request[1] = Integer.parseInt(this.resourceField2.getText().trim()); request[2] = Integer.parseInt(this.resourceField3.getText().trim()); return safetyChecker.BankerCheck(processId); } //对输入框中的输入信息作检查,输入正确就返回true private boolean checkInput() { //如果没有输入数据则提示 if ((this.resourceField1.getText().trim().equals("")) || (this.resourceField2.getText().trim().equals("")) || (this.resourceField3.getText().trim().equals(""))) { return false; } //检查是否输入的数字 Pattern pattern = Pattern.compile("[0-9]{1,}"); String str1 = this.resourceField1.getText().trim(); String str2 = this.resourceField2.getText().trim(); String str3 = this.resourceField3.getText().trim(); Matcher matcher1 = pattern.matcher((CharSequence) str1); Matcher matcher2 = pattern.matcher((CharSequence) str2); Matcher matcher3 = pattern.matcher((CharSequence) str3); boolean result1 = matcher1.matches(); boolean result2 = matcher2.matches(); boolean result3 = matcher3.matches(); if (result1 == true && result2 == true && result3 == true) { return true; } else { return false; } } //释放进程的资源 public void freeResource(int n) { for (int j = 0; j < 3; j++) { this.available[j] = this.available[j] + this.max[n][j]; } } //删除已完成的进程 public void deleteProcess(PCB tempPcb) { arrangedQue.remove(tempPcb); } //唤醒一个阻塞的进程:将阻塞队列中的第一个对象加入到就绪队列中 public void wakeUpProcess() { //如何阻塞进程队列不空就唤醒一个进程 if (!barrageQue.isEmpty()) { arrangedQue.add(barrageQue.get(0)); barrageQue.remove(0); } } }
类DispatchMethord:该类是一个抽象类,只有一个返回进程id的方法,要实现不同的算法来调度进程只需要扩展该类即可
import java.util.ArrayList; public abstract class DispatchMethord { //从数组中得到一个合适的进程id号 //由不同的算法类继承该类实现不同的算法 public abstract int getSuitId(ArrayList<PCB> arrayPcb); }
类HighWeight:继承DispatchMethord类,覆盖返回进程id的方法,实现高优先权的调度
import java.util.ArrayList; import java.util.Iterator; public class HighWeight extends DispatchMethord { //高优先权调度算法取得进程id号 public int getSuitId(ArrayList<PCB> arrangedQue) { //记录最高的优先权 int tempWeight = 0; //记录最高优先权的进程id号 int tempId = arrangedQue.get(0).getProcessId(); Iterator<PCB> itr = arrangedQue.iterator(); while (itr.hasNext()) { PCB temp = itr.next(); if (tempWeight < temp.getPrioNumber()) { tempWeight = temp.getPrioNumber(); tempId = temp.getProcessId(); } } return tempId; } }
类FCFS:该类继承DispatchMethord类,实现先来先服务算法
import java.util.ArrayList; import java.util.Iterator; public class FCFS extends DispatchMethord { public int getSuitId(ArrayList<PCB> arrayPcb) { //记录到达时间 int tempTime = 1000; //记录进程id int tempId = arrayPcb.get(0).getProcessId(); PCB tempPCB; Iterator<PCB> itr = arrayPcb.iterator(); while (itr.hasNext()) { tempPCB = itr.next(); if (tempPCB.getArriveTime() < tempTime) { tempTime = tempPCB.getArriveTime(); tempId = tempPCB.getProcessId(); } } return tempId; } }
类BankerSafetyCheck:银行家类,用银行家算法判断进程申请资源后是否会让系统进入不安全状态
import java.util.Iterator; import javax.swing.JTextArea; public class BankerSafetyCheck { private int work[]; private int finish[]; private int request[]; private int available[]; private int[][] need; private int[][] allocation; private ArrayList<PCB> arrangedQue; private ArrayList<PCB> barrageQue; private JTextArea showPaneArea; private int processNum; private RemindFrame remindFrame; public BankerSafetyCheck(int[] work, int[] finish, int[] request, int[] available, int[][] need, int[][] allocation, ArrayList<PCB> arrangeQue, ArrayList<PCB> barrageQue, JTextArea showPaneArea, int processNum) { this.work = work; this.finish = finish; this.request = request; this.need = need; this.available = available; this.allocation = allocation; this.arrangedQue = arrangeQue; this.barrageQue = barrageQue; this.showPaneArea = showPaneArea; this.processNum = processNum; this.remindFrame = new RemindFrame(); } //银行家算法判断是否为安全态 public PCB BankerCheck(int processId) { for (int j = 0; j < 3; j++) { //资源超过need的放入阻塞队列 if (this.request[j] > this.need[processId][j]) { showPaneArea.append("\n\t现在申请的资源超过前面定义的最大资源,进程" + processId + "阻塞!\n"); remindFrame.showRemindInfo("现在申请的资源超过前面定义的最大资源,进程" + processId + "阻塞!", "进程阻塞"); this.StopProcess(processId); return null; } //判断系统中是否有足够的资源 if (this.request[j] > this.available[j]) { showPaneArea.append("\n\t系统中没有足够的资源,进程" + processId + "阻塞!\n"); remindFrame.showRemindInfo("系统中没有足够的资源,进程" + processId + "阻塞!", "进程阻塞"); this.StopProcess(processId); return null; } } //如果通过上面的检查就进行:安全性检查 return this.SecurityChick(processId); } //安全性检查 private PCB SecurityChick(int processId) { //改变系统资源 this.changeSystemDate(processId); //系统安全性检查,如果不安全则将虚拟分配的资源复原 if (this.check() == false) { //回滚已分配的资源 this.freeRequ(processId); showPaneArea.append("\t进程" + processId + "分配资源后系统不安全,阻塞!"); remindFrame.showRemindInfo("进程" + processId + "分配资源后系统不安全,阻塞!", "进程阻塞信息"); this.StopProcess(processId); return null; } else { //通过系统安全性检查,则进程调度成功 this.showPaneArea.append("\n\t\t进程" + processId + "调度成功\n"); remindFrame.showRemindInfo("进程" + processId + "调度成功", "调度成功"); //根据进程id号取得进程在就绪队列中的对象 PCB temp = null; Iterator<PCB> itr = arrangedQue.iterator(); while (itr.hasNext()) { temp = itr.next(); if (temp.getProcessId() == processId) { break; } } return temp; } } //改变系统资源 private void changeSystemDate(int processId) { int j = 0; for (j = 0; j < 3; j++) { this.available[j] = this.available[j] - this.request[j]; this.allocation[processId][j] = this.allocation[processId][j] + this.request[j]; this.need[processId][j] = this.need[processId][j] - this.request[j]; } } //安全算法:检测系统分配资源给该进程后是否会进入不安全状态 private boolean check() { int i = 0, j = 0, a = 0; for (j = 0; j < 3; j++) { this.work[j] = this.available[j]; } while (i < processNum) { a = 0; for (j = 0; j < 3; j++) { if (this.finish[i] == 0 && this.need[i][j] <= this.work[j]) { a = a + 1; } } if (a == 3) { this.freeWork(i); i = 0; } else { i++; } }//while a = 0; for (i = 0; i < processNum; i++) { if (this.finish[i] == 0) { a = a + 1; } } if (a != 0) { return false; } else { return true; } } //释放银行家算法中虚拟分配的资源 private void freeWork(int n) { int j; for (j = 0; j < 3; j++) { this.work[j] = this.work[j] + this.allocation[n][j]; } this.finish[n] = 1; } //将虚拟分配的资源回滚 private void freeRequ(int n) { int j; for (j = 0; j < 3; j++) { this.available[j] = this.available[j] + this.request[j]; this.allocation[n][j] = this.allocation[n][j] - this.request[j]; this.need[n][j] = this.need[n][j] + this.request[j]; } } //阻塞进程:将进程从就绪队列加入到阻塞队列中 private void StopProcess(int processId) { int index = -1; Iterator<PCB> itr = arrangedQue.iterator(); while (itr.hasNext()) { PCB temp = itr.next(); index++; if (temp.getProcessId() == processId) { this.barrageQue.add(temp); arrangedQue.remove(index); break; } } } }
类System:系统类,包含系统的资源
public class System { //目前系统中可用的资源数 private static int[] available = new int[]{9, 5, 3}; //取得系统可用资源 public static int[] getSystemResource() { return System.available; } //修改系统可用资源 public static void setSystemResource(int[] available) { System.available = available; } }
类RemindFrame:提醒类,用于给用户提示信息使用
public class RemindFrame { //主窗体 private static Management management = null; //设置提示框的父窗体 public static void setFatherFrame(Management management){ RemindFrame.management = management; } //显示提示对话框 public void showRemindInfo(String contentStr, String titleStr){ JOptionPane.showMessageDialog(management, contentStr, titleStr, JOptionPane.INFORMATION_MESSAGE); } }