银行家算法(java swing)界面
代码
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class BankerSwing { JFrame jf = new JFrame("银行家算法"); JPanel jp1 = new JPanel(); JTextField jtf1, jtf2, jtf3, jtf4; JComboBox jcb1; JButton jb1, jb2, jb3, jb4; JTextArea jta1; private int numResource = 3; private int numThread = 100; private int p = 0; // 当前处理的线程 int[] Available = new int[numResource]; // 空闲资源 int[][] Max = new int[numThread][numResource]; // 最大需求资源 int[][] Allocation = new int[numThread][numResource]; // 占有资源 int[][] Need = new int[numThread][numResource]; // 需求资源 int[][] Request = new int[numThread][numResource]; // 申请资源 int[] Work = new int[numResource]; // 辅助空间 // 结果展示 public void ShowFrame(){ jf.setSize(530, 350); //大小 jf.setAlwaysOnTop(true); jf.setResizable(false);//不可拖动 jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 初始化 jtf1 = new JTextField(3); jtf2 = new JTextField(3); jtf3 = new JTextField(3); jtf4 = new JTextField(3); String s[] = {"Max","Allocation","Available","Request"}; jcb1 = new JComboBox(s); jb1 = new JButton("确定"); jb2 = new JButton("例子"); jb3 = new JButton("清零"); jb4 = new JButton("撤销"); // 底部布局 jp1.add(jcb1); jp1.add(new JLabel("ID:")); jp1.add(jtf1); jp1.add(new JLabel("A:")); jp1.add(jtf2); jp1.add(new JLabel("B:")); jp1.add(jtf3); jp1.add(new JLabel("C:")); jp1.add(jtf4); jp1.add(jb1); jb1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == jb1) { if(jcb1.getSelectedItem() == "Allocation"){//设置已占用资源 try{ p = Integer.parseInt(jtf1.getText()); if (p > 4) { JOptionPane.showMessageDialog(jf, "进程ID在0-4之间!","提示",JOptionPane.WARNING_MESSAGE); jtf1.setText(""); return; } if (Integer.parseInt(jtf2.getText()) < 0 || Integer.parseInt(jtf3.getText()) < 0 || Integer.parseInt(jtf4.getText()) < 0) { JOptionPane.showMessageDialog(jf, "资源数不能小于0!", "提示", JOptionPane.WARNING_MESSAGE); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); return; } if(Integer.parseInt(jtf2.getText()) > Max[p][0] || Integer.parseInt(jtf3.getText()) > Max[p][1] || Integer.parseInt(jtf4.getText()) > Max[p][2]){ JOptionPane.showMessageDialog(jf, "占用资源大于最大需求资源(未定义最大需求资源)", "提示", JOptionPane.WARNING_MESSAGE); jtf1.setText(""); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); return; } Allocation[p][0] = Integer.parseInt(jtf2.getText()); Need[p][0] = Max[p][0] - Allocation[p][0]; Allocation[p][1] = Integer.parseInt(jtf3.getText()); Need[p][1] = Max[p][1] - Allocation[p][1]; Allocation[p][2] = Integer.parseInt(jtf4.getText()); Need[p][2] = Max[p][2] - Allocation[p][2]; } catch(Exception d) { JOptionPane.showMessageDialog(jf, "输入有误!请重新输入!", "提示", JOptionPane.WARNING_MESSAGE); ShowData(); return; } ShowData(); jta1.append("\n\n 已占有资源设置成功!"); } else if (jcb1.getSelectedItem() == "Max") { try { p = Integer.parseInt(jtf1.getText()); if (p > 4) { JOptionPane.showMessageDialog(jf, "进程ID在0-4之间!", "提示", JOptionPane.WARNING_MESSAGE); jtf1.setText(""); return; } if (Integer.parseInt(jtf2.getText()) < 0 || Integer.parseInt(jtf3.getText()) < 0 || Integer.parseInt(jtf4.getText()) < 0) { JOptionPane.showMessageDialog(jf, "资源数不能小于0!", "提示", JOptionPane.WARNING_MESSAGE); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); return; } if(Integer.parseInt(jtf2.getText()) < Allocation[p][0] || Integer.parseInt(jtf3.getText()) < Allocation[p][1] || Integer.parseInt(jtf4.getText()) < Allocation[p][2]){ JOptionPane.showMessageDialog(jf, "最大需求资源小于已占有资源!", "提示", JOptionPane.WARNING_MESSAGE); jtf1.setText(""); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); return; } Max[p][0] = Integer.parseInt(jtf2.getText()); Need[p][0] = Max[p][0] - Allocation[p][0]; Max[p][1] = Integer.parseInt(jtf3.getText()); Need[p][1] = Max[p][1] - Allocation[p][1]; Max[p][2] = Integer.parseInt(jtf4.getText()); Need[p][2] = Max[p][2] - Allocation[p][2]; } catch(Exception d) { JOptionPane.showMessageDialog(jf, "输入有误!请重新输入!", "提示", JOptionPane.WARNING_MESSAGE); ShowData(); return; } ShowData(); jta1.append("\n\n 最大需求设置成功!"); } else if (jcb1.getSelectedItem()=="Available"){//设置可用资源 try{ if (Integer.parseInt(jtf2.getText()) < 0 || Integer.parseInt(jtf3.getText()) < 0 || Integer.parseInt(jtf4.getText()) < 0) { JOptionPane.showMessageDialog(jf, "资源数不能小于0!", "提示", JOptionPane.WARNING_MESSAGE); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); return; } Available[0] = Integer.parseInt(jtf2.getText()); Available[1] = Integer.parseInt(jtf3.getText()); Available[2] = Integer.parseInt(jtf4.getText()); }catch(Exception d) { JOptionPane.showMessageDialog(jf, "您输入有误!请重新输入!", "提示", JOptionPane.WARNING_MESSAGE); ShowData(); return; } ShowData(); jta1.append("\n\n 可用资源设置成功!"); } else if(jcb1.getSelectedItem() == "Request"){ try{ p = Integer.parseInt(jtf1.getText()); if (p > 4) { JOptionPane.showMessageDialog(jf, "进程ID在0-4之间!", "提示", JOptionPane.WARNING_MESSAGE); jtf1.setText(""); return; } if (Integer.parseInt(jtf2.getText()) < 0 || Integer.parseInt(jtf3.getText()) < 0 || Integer.parseInt(jtf4.getText()) < 0) { JOptionPane.showMessageDialog(jf, "资源数不能小于0!", "提示", JOptionPane.WARNING_MESSAGE); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); return; } Request[p][0] = Integer.parseInt(jtf2.getText()); Request[p][1] = Integer.parseInt(jtf3.getText()); Request[p][2] = Integer.parseInt(jtf4.getText()); }catch(Exception d) { JOptionPane.showMessageDialog(jf, "您输入有误!请重新输入!", "提示", JOptionPane.WARNING_MESSAGE); ShowData(); return; } int[] order = new int[numThread]; if(bankerKernel(p, order)){ ShowData(); jta1.append("\n\n 通过安全性检查!安全序列为:"); for(int i = 0; i < order.length; i++)//打印安全序列 jta1.append("P"+order[i]+" "); JOptionPane.showMessageDialog(jf, "申请成功,资源已经分配~~~","提示",JOptionPane.INFORMATION_MESSAGE); }else { ShowData(); for (int i = 0; i < numResource; i++) { Request[p][i] = 0; } JOptionPane.showMessageDialog(jf, "找不到安全序列! 不批准请求!", "提示", JOptionPane.WARNING_MESSAGE); } }else{ ShowData(); jta1.append("\n\n 系统资源不足!"); } } } }); // 确定按键功能设定 jp1.setBackground(new java.awt.Color(128,255,128)); // 右边布局,竖直 Box vBox = Box.createVerticalBox(); vBox.add(Box.createVerticalStrut(60)); // 添加空白 vBox.add(jb2); vBox.add(Box.createVerticalStrut(20)); // 添加空白 vBox.add(jb3); vBox.add(Box.createVerticalStrut(20)); // 添加空白 vBox.add(jb4); jb2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == jb2){ init(); ShowData(); } } }); // 例子按键功能设定 jb3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == jb3){ reset(); ShowData(); } } }); // 清零按键功能设定 jb4.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == jb4){ if(revocation()) JOptionPane.showMessageDialog(jf, "撤销成功~~~","提示", JOptionPane.INFORMATION_MESSAGE); else JOptionPane.showMessageDialog(jf, "无撤销内容!","提示", JOptionPane.WARNING_MESSAGE); ShowData(); } } }); // 撤销按键功能设定 jf.add(jp1,"South"); // 布局底部 jf.add(vBox,"After");// 右边 // 展示中间的文本 jta1= new JTextArea(); ShowData(); jta1.setLineWrap(true); jta1.setBackground(Color.white); jta1.setEditable(false); jf.add(jta1,BorderLayout.CENTER); // 结果展示 jf.setVisible(true); } // 展示数据 public void ShowData() { jta1.setText(" Max \tAllocation \t Need Available\n"); jta1.append("\n" + " 资源 " + " A B C " + " A B C " + " A B C " + " A B C"); jta1.append("\n 进程\n P0" + " " + + Max[0][0] + " " + Max[0][1] + " " +Max[0][2] + " " + " " + Allocation[0][0] + " " + Allocation[0][1] + " " + Allocation[0][2] + " " + " " + Need[0][0] + " " + Need[0][1] + " " + Need[0][2] + " " + " " + Available[0] + " " + Available[1] + " " + Available[2]); for (int i = 1; i < 5; i++) { jta1.append("\n\n P" + i + " " + " " + Max[i][0] + " " + Max[i][1] + " " + Max[i][2] + " " + " " + Allocation[i][0] + " " + Allocation[i][1] + " " + Allocation[i][2] + " " + " " + Need[i][0] + " " + Need[i][1] + " " + Need[i][2] + " "); } jtf1.setText(""); jtf2.setText(""); jtf3.setText(""); jtf4.setText(""); } // 算法核心流程 public boolean bankerKernel(int num, int[] order){ // 判断资源申请的数量是否符合空闲资源和需要资源 for(int i = 0; i < numResource; i++){ if(Request[num][i] > Need[num][i]) { System.out.println("错误:进程P" + num + "的申请,超出最大需求量Need。"); return false; } else if(Request[num][i] > Available[i]){ System.out.println("错误:当前没有足够的资源可申请,进程P" + num + "需等待。"); return false; } } // 更新空闲资源,占用资源和需要资源 for (int i = 0; i < numResource; i++) { Allocation[num][i] += Request[num][i]; Available[i] -= Request[num][i]; Need[num][i] -= Request[num][i]; } // 安全性检查 if(isSafe(order)){ return true; } // 不安全,返回申请资源前的状态 for (int i = 0; i < numResource; i++) { Allocation[num][i] -= Request[num][i]; Available[i] += Request[num][i]; Need[num][i] += Request[num][i]; } return false; } // 安全性检查 public boolean isSafe(int[]order){ int count = 0; // 安全的线程数量 int k = 0; int circle = 0; // 循环次数 boolean[] Finish = new boolean[numThread]; // 线程是否进入安全序列 for (int i = 0; i < numResource; i++) { Finish[i] = false; } copyWork(); while(true){ for (int i = 0; i < numThread; i++) { if(Finish[i] == false){ for (k = 0; k < numResource; k++) { if(Work[k] < Need[i][k]) break; } // 空闲资源满足线程所需要的资源 if(k == numResource){ order[count++] = i; Finish[i] = true; // 释放资源 for (int j = 0; j < numResource; j++) { Work[j] += Allocation[i][j]; } } } } circle++; if(count == numThread){ System.out.print("存在一个安全序列:"); for (int i = 0; i < numThread; i++){//输出安全序列 System.out.print("P" + order[i] + " "); } System.out.println("故当前可分配!"); return true; } // 如果进入安全序列的线程数小于循环次数,说明不存在能安全完成的线程 if(count < circle){ System.out.println("警告:申请使得系统处于不安全状态,申请失败。"); return false; } } } // 使用辅助空间 public void copyWork(){ for (int i = 0; i < numResource; i++) { Work[i] = Available[i]; } } // 初始化一个例子 public void init(){ numThread = 5; numResource = 3; Available[0] = 3; Available[1] = 3; Available[2] = 2; Max[0][0] = 7; Max[0][1] = 5; Max[0][2] = 3; Max[1][0] = 3; Max[1][1] = 2; Max[1][2] = 2; Max[2][0] = 9; Max[2][1] = 0; Max[2][2] = 2; Max[3][0] = 2; Max[3][1] = 2; Max[3][2] = 2; Max[4][0] = 4; Max[4][1] = 3; Max[4][2] = 3; Allocation[0][0] = 0; Allocation[0][1] = 1; Allocation[0][2] = 0; Allocation[1][0] = 2; Allocation[1][1] = 0; Allocation[1][2] = 0; Allocation[2][0] = 3; Allocation[2][1] = 0; Allocation[2][2] = 2; Allocation[3][0] = 2; Allocation[3][1] = 1; Allocation[3][2] = 1; Allocation[4][0] = 0; Allocation[4][1] = 0; Allocation[4][2] = 2; for (int i = 0; i < numThread; i++) { for (int j = 0; j < numResource; j++) { Need[i][j] = Max[i][j] - Allocation[i][j]; } } } // 清零 public void reset(){ for (int i = 0; i < numThread; i++) { for (int j = 0; j < numResource; j++) { Max[i][j] = 0; Allocation[i][j] = 0; Need[i][j] = 0; Available[j] = 0; } } } // 撤回 public boolean revocation(){ if(Request[p][0] == 0 && Request[p][1] == 0 && Request[p][2] == 0) return false; for (int i = 0; i < numResource; i++) { Allocation[p][i] -= Request[p][i]; Need[p][i] = Max[p][i] - Allocation[p][i]; Available[i] += Request[p][i]; Request[p][i] = 0; } return true; } public static void main(String[] args) { BankerSwing B = new BankerSwing(); B.ShowFrame(); } }
结果截图
1. 成功运行。
2. 申请成功后可以进行撤销。
3. 若未成功申请无法进行撤销操作。
4. 不安全,申请失败。
5. 设置Allocation比Max大时。
6. 在已经有Allocation时,想修改Max数据,为了防止出错。
7. 成功设置Max。
8. 成功设置Allocation。
9. 成功设置Available。