银行家算法(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。

 

 

posted @ 2020-05-10 15:57  德狗咬不过狗  阅读(1251)  评论(0编辑  收藏  举报