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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM