java图形化进程调度设计短作业优先
时间: 2023-12-13 21:22:01 浏览: 130
下面是一个使用Java图形化界面实现短作业优先进程调度算法的示例代码:
```java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ShortestJobFirst {
private List<Process> processes;
private List<Process> readyQueue;
private Process currentProcess;
private int currentTime;
private int totalTurnaroundTime;
private int totalWaitingTime;
private int totalProcesses;
private JFrame frame;
private JButton addButton;
private JButton startButton;
private JTable table;
private ProcessTableModel tableModel;
public ShortestJobFirst() {
processes = new ArrayList<>();
readyQueue = new ArrayList<>();
tableModel = new ProcessTableModel();
initUI();
}
private void initUI() {
frame = new JFrame("Shortest Job First");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
addButton = new JButton("Add Process");
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
AddProcessDialog dialog = new AddProcessDialog(frame);
dialog.setVisible(true);
if (dialog.isConfirmed()) {
addProcess(dialog.getProcess());
}
}
});
startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
start();
}
});
JPanel panel = new JPanel(new BorderLayout());
panel.add(addButton, BorderLayout.WEST);
panel.add(startButton, BorderLayout.EAST);
table = new JTable(tableModel);
JScrollPane scrollPane = new JScrollPane(table);
frame.add(panel, BorderLayout.NORTH);
frame.add(scrollPane, BorderLayout.CENTER);
}
public void addProcess(Process process) {
processes.add(process);
tableModel.addRow(new Object[]{process.getName(), process.getBurstTime()});
}
public void start() {
sortProcesses();
currentTime = 0;
totalTurnaroundTime = 0;
totalWaitingTime = 0;
totalProcesses = processes.size();
currentProcess = null;
readyQueue.clear();
tableModel.clearMarks();
while (!processes.isEmpty() || !readyQueue.isEmpty() || currentProcess != null) {
updateReadyQueue();
updateCurrentProcess();
currentTime++;
}
double avgTurnaroundTime = (double) totalTurnaroundTime / totalProcesses;
double avgWaitingTime = (double) totalWaitingTime / totalProcesses;
JOptionPane.showMessageDialog(frame, String.format("Average Turnaround Time: %.2f\nAverage Waiting Time: %.2f", avgTurnaroundTime, avgWaitingTime));
}
private void sortProcesses() {
Collections.sort(processes, new Comparator<Process>() {
@Override
public int compare(Process o1, Process o2) {
return o1.getBurstTime() - o2.getBurstTime();
}
});
}
private void updateReadyQueue() {
for (Process process : processes) {
if (process.getArrivalTime() == currentTime) {
readyQueue.add(process);
}
}
processes.removeAll(readyQueue);
}
private void updateCurrentProcess() {
if (currentProcess != null) {
currentProcess.execute();
if (currentProcess.isFinished()) {
totalTurnaroundTime += currentTime - currentProcess.getArrivalTime();
totalWaitingTime += currentTime - currentProcess.getArrivalTime() - currentProcess.getBurstTime();
currentProcess = null;
}
}
if (currentProcess == null) {
if (!readyQueue.isEmpty()) {
currentProcess = readyQueue.remove(0);
currentProcess.setMarked(true);
}
}
tableModel.fireTableDataChanged();
}
public void show() {
frame.setVisible(true);
}
public static void main(String[] args) {
ShortestJobFirst sjf = new ShortestJobFirst();
sjf.show();
}
}
class Process {
private String name;
private int arrivalTime;
private int burstTime;
private int remainingTime;
private boolean marked;
public Process(String name, int arrivalTime, int burstTime) {
this.name = name;
this.arrivalTime = arrivalTime;
this.burstTime = burstTime;
this.remainingTime = burstTime;
this.marked = false;
}
public String getName() {
return name;
}
public int getArrivalTime() {
return arrivalTime;
}
public int getBurstTime() {
return burstTime;
}
public boolean isMarked() {
return marked;
}
public void setMarked(boolean marked) {
this.marked = marked;
}
public void execute() {
remainingTime--;
}
public boolean isFinished() {
return remainingTime == 0;
}
}
class ProcessTableModel extends AbstractTableModel {
private List<Object[]> data;
private String[] columnNames;
private int[] marks;
public ProcessTableModel() {
data = new ArrayList<>();
columnNames = new String[]{"Process Name", "Burst Time"};
marks = new int[0];
}
public void addRow(Object[] row) {
data.add(row);
fireTableDataChanged();
}
public void clearMarks() {
marks = new int[0];
fireTableDataChanged();
}
public void setMarks(int[] marks) {
this.marks = marks;
fireTableDataChanged();
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object[] row = data.get(rowIndex);
return row[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return getValueAt(0, columnIndex).getClass();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Object[] row = data.get(rowIndex);
row[columnIndex] = aValue;
fireTableCellUpdated(rowIndex, columnIndex);
}
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
return new MarkedCellRenderer(marks, row);
}
}
class MarkedCellRenderer extends DefaultTableCellRenderer {
private int[] marks;
private int row;
public MarkedCellRenderer(int[] marks, int row) {
this.marks = marks;
this.row = row;
}
@Override
protected void paintComponent(Graphics g) {
if (marks.length > row && marks[row] > 0) {
setBackground(Color.YELLOW);
} else {
setBackground(Color.WHITE);
}
super.paintComponent(g);
}
}
class AddProcessDialog extends JDialog {
private JTextField nameField;
private JSpinner arrivalTimeSpinner;
private JSpinner burstTimeSpinner;
private JButton okButton;
private JButton cancelButton;
private boolean confirmed;
private Process process;
public AddProcessDialog(JFrame parent) {
super(parent, "Add Process", true);
setSize(300, 150);
nameField = new JTextField();
arrivalTimeSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 100, 1));
burstTimeSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1));
okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
confirmed = true;
process = new Process(nameField.getText(), (int) arrivalTimeSpinner.getValue(), (int) burstTimeSpinner.getValue());
dispose();
}
});
cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
JPanel panel = new JPanel(new GridLayout(4, 2));
panel.add(new JLabel("Process Name:"));
panel.add(nameField);
panel.add(new JLabel("Arrival Time:"));
panel.add(arrivalTimeSpinner);
panel.add(new JLabel("Burst Time:"));
panel.add(burstTimeSpinner);
panel.add(okButton);
panel.add(cancelButton);
setContentPane(panel);
}
public boolean isConfirmed() {
return confirmed;
}
public Process getProcess() {
return process;
}
}
```
该程序使用Swing实现了一个简单的图形界面,用户可以通过添加进程按钮添加进程,然后通过开始按钮启动短作业优先进程调度算法。程序使用了`ProcessTableModel`类来管理进程表格的数据,该类继承了`AbstractTableModel`,并实现了相关方法,可以自定义表格的内容和行为。程序使用了`MarkedCellRenderer`类来为当前正在执行的进程设置标记,以便用户可以清楚地看到当前正在执行的进程。
在短作业优先进程调度算法中,进程按照执行时间从短到长排序,然后依次执行,直到所有进程都执行完毕。在该程序中,使用`sortProcesses`方法对进程进行排序,然后在`updateReadyQueue`方法中将到达时间为当前时间的进程加入就绪队列中。在`updateCurrentProcess`方法中,程序先执行当前进程,然后检查当前进程是否已经执行完毕,如果已经执行完毕,则将该进程从就绪队列中移除,并更新统计数据。然后程序检查就绪队列中是否有进程,如果有,则将其中一个进程作为当前进程执行。最后,程序使用`tableModel.fireTableDataChanged()`方法来通知表格模型更新表格的显示,以便用户可以看到当前进程的标记。
最后,程序使用`JOptionPane.showMessageDialog`方法显示平均周转时间和平均等待时间。
阅读全文