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