Java教程

银行家算法(Java实现)

本文主要是介绍银行家算法(Java实现),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

银行家算法是最著名的避免死锁的算法。下面用Java来实现它。


代码

主要使用到的类是BankerAlgorithm

并且进程的信息是从文件中读入的。

1、使用到的变量

private static final int W = 10, R = 10;
int M, N; //总进程数、资源种类
int[] ALL_RESOURCE = new int[W]; //默认各种资源总数目为10种
int[][] MAX = new int[W][R]; //M个进程对N类资源最大资源需求量
int[] AVAILABLE = new int[R]; // 系统可用资源数
int[][] ALLOCATION = new int[W][R]; // M个进程已经得到N类资源的资源量
int[][] NEED = new int[W][R]; // M个进程还需要N类资源的资源量
int[] Request = new int[R]; // 请求资源个数
int[] P = new int[W];     //进程安全序列
String fileName = "D:\\data.txt";

2、构造器

public BankerAlgorithm() throws FileNotFoundException {
    System.out.println("\t\t   银 行 家 算 法");
    System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    Scanner sc = new Scanner(new FileReader(fileName));
    System.out.print("请输入总进程数:");
    M = sc.nextInt();
    System.out.println(M);
    System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.print("请输入总资源种类:");
    N = sc.nextInt();
    System.out.println(N);
    System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("请输入各类资源总数:(需要输入数为" + N + "个)");
    for (int i = 0; i < N; i++) {
        ALL_RESOURCE[i] = sc.nextInt();
        System.out.print(ALL_RESOURCE[i] + " ");
    }
    System.out.println("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("输入各进程所需最大的各类资源的数量:(需要输入数为" + M
            * N + "个)");
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            do {
                MAX[i][j] = sc.nextInt();
                if (MAX[i][j] > ALL_RESOURCE[j])
                    System.out.println("\n占有资源超过了声明的该资源总数,请重新输入");
            } while (MAX[i][j] > ALL_RESOURCE[j]);
            System.out.print(MAX[i][j] + " ");
        }
        System.out.println();
    }
    System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("输入各进程已经占据的各类资源的数量:(需要输入数为" + M
            * N + "个)");
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            do {
                ALLOCATION[i][j] = sc.nextInt();
                if (ALLOCATION[i][j] > MAX[i][j])
                    System.out.println("\n占有资源超过了声明的最大资源,请重新输入");
            } while (ALLOCATION[i][j] > MAX[i][j]);
            System.out.print(ALLOCATION[i][j] + " ");
        }
        System.out.println();
    }
    //初始化资源数量
    int p;
    for (int j = 0; j < N; j++) {
        p = ALL_RESOURCE[j];
        for (int i = 0; i < M; i++) {
            p = p - ALLOCATION[i][j];// 减去已经被占据的资源
            AVAILABLE[j] = p;
            if (AVAILABLE[j] < 0)
                AVAILABLE[j] = 0;
        }
    }
    for (int i = 0; i < M; i++)
        for (int j = 0; j < N; j++)
            NEED[i][j] = MAX[i][j] - ALLOCATION[i][j];
    output();
    bank();
}

3、输出

public void output() {
    int i, j;
    System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("各种资源的总数量:");
    for (j = 0; j < N; j++)
        System.out.print(" 资源" + j + ": " + ALL_RESOURCE[j]);
    System.out.println("\n" + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("目前各种资源可利用的数量为:");
    for (j = 0; j < N; j++)
        System.out.print(" 资源" + j + ": " + AVAILABLE[j]);
    System.out.println("\n" + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("各进程还需要的资源数量:");
    System.out.print("      ");
    for (i = 0; i < N; i++)
        System.out.print("资源" + i + "   \t");
    System.out.println();
    for (i = 0; i < M; i++) {
        System.out.print("进程" + i + ":\t");
        for (j = 0; j < N; j++)
            System.out.print(NEED[i][j] + "\t\t");
        System.out.println();
    }
    System.out.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
    System.out.println("各进程已经得到的资源量: ");
    System.out.print("      ");
    for (i = 0; i < N; i++)
        System.out.print("资源" + i + "   \t");
    System.out.println();
    for (i = 0; i < M; i++) {
        System.out.print("进程" + i + ":\t");
        for (j = 0; j < N; j++)
            System.out.print(ALLOCATION[i][j] + "\t\t");
        System.out.println();
    }
    System.out.println();
}

4、资源分配与回收

//进行资源分配
public void distribute(int k) {
     for (int j = 0; j < N; j++) {
         AVAILABLE[j] -= Request[j];
         ALLOCATION[k][j] += Request[j];
         NEED[k][j] -= Request[j];
     }
 }
 
 //撤销资源分配(与分配相反的操作)
 public void restore(int k) {
     for (int j = 0; j < N; j++) {
         AVAILABLE[j] += Request[j];
         ALLOCATION[k][j] -= Request[j];
         NEED[k][j] += Request[j];
     }
 }

5、安全性检查

//安全性检查
public boolean check() {
    int[] WORK = new int[R], FINISH = new int[W];
    for (int j = 0; j < N; j++) WORK[j] = AVAILABLE[j];
    for (int i = 0; i < M; i++) FINISH[i] = 0;
    int j;
    int l = 0;
    for (int i = 0; i < M; i++) {
        if (FINISH[i] == 1) continue;
        else {
            for (j = 0; j < N; j++) {
                if (NEED[i][j] > WORK[j]) break;
            }
            if (j == N) {  //说明该行的need需求小于work,可以尝试分配
                FINISH[i] = 1; //说明该行(进程)状态为已分配
                //回收资源
                for (int k = 0; k < N; k++)
                    WORK[k] += ALLOCATION[i][k];
                P[l++] = i; //加入安全队列
                i = -1;
            } else {
                continue;
            }
        }
        if (l == M) { //此时代表安全队列已满,说明当前分配安全
            System.out.println("\n 经安全性检查,系统安全,本次分配成功。\n");
            System.out.println("安全序列是:");
            for (i = 0; i < l; i++) {
                System.out.print(P[i]);
                if (i != l - 1) System.out.print("-->");
            }
            System.out.println();
            return true;
        }
    }
    System.out.println("\n 系统不安全!!! 本次资源申请不成功!!!\n");
    return false;
}

6、银行家算法

public void bank() {
    Scanner sc = new Scanner(System.in);
    int i, j;
    char flag = 'Y';
    while (flag == 'Y' || flag == 'y') {
        i = -1;
        //输入需要申请资源的进程号
        while (i < 0 || i >= M) {
            System.out.print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + "\n" + " 请输入需申请资源的进程号:");
            i = sc.nextInt();
            if (i < 0 || i >= M)
                System.out.println(" 输入的进程号不存在,重新输入!");
        }
        System.out.println("请输入进程" + i + "申请各类资源的数量:");
        for (j = 0; j < N; j++) {
            System.out.print(" 资源" + j + ": ");
            Request[j] = sc.nextInt();
            //输入请求大于需求,即不安全
            if (Request[j] > NEED[i][j]) {
                System.out.println("\n 进程" + i + "申请的资源数大于进程" + i + "还需要" + j + "类资源的数量!" + " 若继续执行系统将处于不安全状态!");
                flag = 'N';
                break;
            } else {
                //输入需求大于可用,依旧不安全
                if (Request[j] > AVAILABLE[j]) {
                    System.out.println("\n 进程" + i + "申请的资源数大于进程" + i + "还需要" + j + "类资源的数量!" + " 若继续执行系统将处于不安全状态!");
                    flag = 'N';
                    break;
                }
            }
        }
        if (flag == 'Y' || flag == 'y') {
            distribute(i); // 调用distribute(i),改变资源数
            if (!check()) { // 若系统不安全
                restore(i); // 调用restore(i)函数,恢复资源数
                output();   // 输出资源分配情况
            } else       // 若系统安全
                output(); // 输出资源分配情况
        } else
            System.out.println();
        System.out.print(" 是否继续银行家算法演示,按'Y'或'y'键继续,按'N'或'n'键退出演示: ");
        flag = sc.next().charAt(0);
    }
}

7、调用

由于把主要算法最终都放在了构造器之中,因而使用时直接new BankerAlgorithm()即可。

这篇关于银行家算法(Java实现)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!