java找出银行家算法所有安全序列

/**
 *  默认最后一行为剩余的资源数
 */
public class Os {
private static int resourceNum; // 资源数,A,B,C...
private static boolean flag = false; // 判断有无找到一条安全路径
private static List<Integer> request= new ArrayList<Integer>(); //请求的进程资源
private static int index; //发出请求的进程号

public static void main(String[] args) {
List<List<Integer>> process = new ArrayList<List<Integer>>(); // 进程
List<Integer> processState = new ArrayList<Integer>(); // 记录进程状态,有无跑过
// 读取文件信息
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(new File("process.txt")), "UTF-8"));
String lineTxt = null;
while ((lineTxt = br.readLine()) != null) {
String[] names = lineTxt.split(" ");
List<Integer> temp = new ArrayList<Integer>();
for (int i = 1; i < names.length; i++) {
temp.add(Integer.valueOf(names[i]));
}
process.add(temp);
}
br.close();
} catch (Exception e) {
System.err.println("read errors :" + e.getMessage());
}
resourceNum = process.get(0).size() / 2;
needResource(process);
while (true) {
showProcess(process);
List<Integer> available = process.get(process.size() - 1); // 当前拥有的资源数
System.out.println("available" + available);
System.out.println("输入请求资源的进程数(0-" + (process.size() - 2) + "):");
Scanner in = new Scanner(System.in);
index = in.nextInt();
if (index < 0 || index > (process.size() - 1)) {
break;
}
System.out.println("请输入请求资源的数量");
Scanner re = new Scanner(System.in);
String inRequest=re.nextLine();
String[] r=inRequest.split(" "); //将输入的字符串以空格符进行分割
request.clear();
for(int i=0;i<r.length;i++){
request.add(Integer.valueOf(r[i]));
}
if (judgeFirst(process.get(index), available, request)) {
judge(process, available, processState);
} else {
System.out.println("系统进入不安全状态,不分配资源");
}
}
}

// 判断request和available,need的资源数
public static boolean judgeFirst(List<Integer> process, List<Integer> available, List<Integer> request) {
int i;
for (i = 0; i < resourceNum; i++) {
// 如果request>available或者request>need则不符合要求
if (process.get(resourceNum * 2 + i) < request.get(i) || available.get(i) < request.get(i)) {
break;
}
}
// request符合要求,将该 process和available改变
if (i >= resourceNum) {
for (int j = 0; j < resourceNum; j++) {
process.set(resourceNum * 2 + j, process.get(resourceNum * 2 + j) - request.get(j)); // 该进程need改变
process.set(resourceNum + j, process.get(resourceNum + j) + request.get(j)); // 该进程alloction改变
available.set(j, available.get(j) - request.get(j));
}
return true;
}
return false;
}

//回滚操作
public static void previous(List<Integer> process, List<Integer> available, List<Integer> request){
for (int j = 0; j < resourceNum; j++) {
process.set(resourceNum * 2 + j, process.get(resourceNum * 2 + j) + request.get(j)); // 该进程need改变
process.set(resourceNum + j, process.get(resourceNum + j) - request.get(j)); // 该进程alloction改变
available.set(j, available.get(j) + request.get(j));
}
}

// 将当前进程打印
public static void showProcess(List<List<Integer>> process) {
System.out.println("process [max,allocation,need]");
for (int i = 0; i < process.size() - 1; i++) {
System.out.println("process" + i + process.get(i));
}
}

// 计算Need资源数
public static void needResource(List<List<Integer>> process) {
for (int i = 0; i < process.size() - 1; i++) {
for (int j = 0; j < resourceNum; j++) {
int max = (Integer) process.get(i).get(j); // 需要最大的资源数
int allocation = (Integer) process.get(i).get(resourceNum + j); // 当前拥有的资源数
process.get(i).add(max - allocation);
}
}
}

// 判断available与need
public static void judge(List<List<Integer>> process, List<Integer> available, List<Integer> processState) {
for (int i = 0; i < process.size() - 1; i++) { // 进程数
if (!processState.contains(i)) // 判断该进程有无跑过,没有跑过则不进行判断
{
int j;
for (j = 0; j < resourceNum; j++) { // 资源数
int availableNum = available.get(j); // 当前某资源拥有的数量
int needNum = (Integer) process.get(i).get(2 * resourceNum + j); // 当前某资源需要的数量
if (availableNum < needNum) // 或某个资源不符合则退出
{
break;
}
}
if (j >= resourceNum) // 找到一个符合资源的进程
{
List<Integer> newProcessState = new ArrayList<Integer>();
newProcessState.addAll(processState);
newProcessState.add(i); // 将跑过的进程进行记录
List<Integer> newAvailable = new ArrayList<Integer>();
for (int length = 0; length < resourceNum; length++) {
int nextAvailable = available.get(length) + (Integer) process.get(i).get(resourceNum + length);
newAvailable.add(nextAvailable); // 更新当前资源数,将获得资源数加上之前的资源数
}
if (newProcessState.size() == process.size() - 1) { // 所有进程遍历完毕表明找到安全路径
flag = true;
System.out.println("进程" + i + "拥有的资源 :" + newAvailable + "跑过的进程:" + newProcessState);
}
judge(process, newAvailable, newProcessState); //进行递归操作
} else {
if (i >= process.size() - 2) {
if (flag) {
System.out.println("所有安全序列打印完毕");
} else {
System.out.println("未找到安全路径,进行回滚操作");
previous(process.get(index),available,request); //进行回滚
}
}
}
}
}
}

}

process.txt格式

process0 7 5 3 0 1 0 
process1 3 2 2 2 0 0
process2 9 0 2 3 0 2
process3 2 2 2 2 1 1
process4 4 3 3 0 0 2
available 3 3 2

说明:每个process的资源数一定为偶数,例如(7,5,3,0,1,0) ,前面3个为max(7,5,3),后面3个位alloction(0,1,0);如果是(7,5,3,4,0,1,0,7),那么前4个为max,后4个为alloction;

运行效果:

process [max,allocation,need]
process0[7, 5, 3, 0, 1, 0, 7, 4, 3]
process1[3, 2, 2, 2, 0, 0, 1, 2, 2]
process2[9, 0, 2, 3, 0, 2, 6, 0, 0]
process3[2, 2, 2, 2, 1, 1, 0, 1, 1]
process4[4, 3, 3, 0, 0, 2, 4, 3, 1]
available[3, 3, 2]
输入请求资源的进程数(0-4):
0
请输入请求资源的数量
0 0 0
进程4拥有的资源 :[10, 5, 7]跑过的进程:[1, 3, 0, 2, 4]
进程2拥有的资源 :[10, 5, 7]跑过的进程:[1, 3, 0, 4, 2]
进程4拥有的资源 :[10, 5, 7]跑过的进程:[1, 3, 2, 0, 4]
进程0拥有的资源 :[10, 5, 7]跑过的进程:[1, 3, 2, 4, 0]
进程2拥有的资源 :[10, 5, 7]跑过的进程:[1, 3, 4, 0, 2]
进程0拥有的资源 :[10, 5, 7]跑过的进程:[1, 3, 4, 2, 0]
进程2拥有的资源 :[10, 5, 7]跑过的进程:[1, 4, 3, 0, 2]
进程0拥有的资源 :[10, 5, 7]跑过的进程:[1, 4, 3, 2, 0]
进程4拥有的资源 :[10, 5, 7]跑过的进程:[3, 1, 0, 2, 4]
进程2拥有的资源 :[10, 5, 7]跑过的进程:[3, 1, 0, 4, 2]
进程4拥有的资源 :[10, 5, 7]跑过的进程:[3, 1, 2, 0, 4]
进程0拥有的资源 :[10, 5, 7]跑过的进程:[3, 1, 2, 4, 0]
进程2拥有的资源 :[10, 5, 7]跑过的进程:[3, 1, 4, 0, 2]
进程0拥有的资源 :[10, 5, 7]跑过的进程:[3, 1, 4, 2, 0]
进程2拥有的资源 :[10, 5, 7]跑过的进程:[3, 4, 1, 0, 2]
进程0拥有的资源 :[10, 5, 7]跑过的进程:[3, 4, 1, 2, 0]
所有安全序列打印完毕

process [max,allocation,need]
process0[7, 5, 3, 0, 1, 0, 7, 4, 3]
process1[3, 2, 2, 2, 0, 0, 1, 2, 2]
process2[9, 0, 2, 3, 0, 2, 6, 0, 0]
process3[2, 2, 2, 2, 1, 1, 0, 1, 1]
process4[4, 3, 3, 0, 0, 2, 4, 3, 1]
available[3, 3, 2]
输入请求资源的进程数(0-4):

可以不停的进行申请,当输入的进程数不在要求内,则会退出循环,比如上述输入5,则会退出循环。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值