├── src └── main │ ├── resources │ ├── application.properties │ └── static │ │ └── index.html │ └── java │ └── com │ └── banker │ ├── entity │ ├── InitNumber.java │ ├── AddRequestDto.java │ ├── FinalDto.java │ └── RestBean.java │ ├── BankerApplication.java │ └── controller │ └── BankController.java ├── .gitattributes ├── README.md └── pom.xml /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=java 2 | *.css linguist-language=java 3 | *.html linguist-language=java 4 | -------------------------------------------------------------------------------- /src/main/java/com/banker/entity/InitNumber.java: -------------------------------------------------------------------------------- 1 | package com.banker.entity; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @Author: Silvery 7 | * @Date: 2023/7/5 15:57 8 | */ 9 | @Data 10 | public class InitNumber { 11 | 12 | Integer processesNumber; 13 | Integer assetsNumber; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/banker/entity/AddRequestDto.java: -------------------------------------------------------------------------------- 1 | package com.banker.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @Author: Silvery 9 | * @Date: 2023/7/6 15:42 10 | */ 11 | @Data 12 | public class AddRequestDto { 13 | Integer processNum; 14 | List requestList; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/banker/entity/FinalDto.java: -------------------------------------------------------------------------------- 1 | package com.banker.entity; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @Author: Silvery 9 | * @Date: 2023/7/5 21:08 10 | */ 11 | @Data 12 | public class FinalDto { 13 | List max; 14 | List allocation; 15 | List need; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/banker/entity/RestBean.java: -------------------------------------------------------------------------------- 1 | package com.banker.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @Author: Silvery 9 | * @Date: 2023/7/5 17:03 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class RestBean { 15 | int code; 16 | T data; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/banker/BankerApplication.java: -------------------------------------------------------------------------------- 1 | package com.banker; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class BankerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(BankerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java-Banker 2 | ## SpringBoot实现银行家算法的一个小Demo 3 | 由于操作系统大型试验的需要,做了一个操作系统中实现银行家算法的小demo 4 | 前端使用了纯html加js控制dom生成元素,全部手撕,没有使用任何框架 5 | 后端使用了java后台,springboot应用程序 6 | 7 | ## 下载使用 8 | 直接clone下代码,配置好自己的maven,启动BankerApplication即可,需要java8及以上版本 9 | 10 | ## BUG 11 | 由于为了完成作业,所以只做到了申请资源,和新建线程的新建部分,新建部分也有一些瑕疵; 12 | 还有释放资源未完成,感兴趣的小伙伴可以尝试一下,本人对此不感兴趣,固大概率不会进行改进升级; 13 | 14 | ## 最后 15 | 如果你也需要写一个web端的银行家算法,这里的功能拿去,过关应该没有问题,如果想拿高分,则需自行升级改进 16 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.13 9 | 10 | 11 | com.banker 12 | banker 13 | 0.0.1-SNAPSHOT 14 | banker 15 | banker 16 | 17 | 8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | true 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-test 33 | test 34 | 35 | 36 | 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-maven-plugin 42 | 43 | 44 | 45 | org.projectlombok 46 | lombok 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/main/java/com/banker/controller/BankController.java: -------------------------------------------------------------------------------- 1 | package com.banker.controller; 2 | 3 | import com.banker.entity.AddRequestDto; 4 | import com.banker.entity.FinalDto; 5 | import com.banker.entity.InitNumber; 6 | import com.banker.entity.RestBean; 7 | import org.springframework.web.bind.annotation.PostMapping; 8 | import org.springframework.web.bind.annotation.RequestBody; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.ArrayList; 13 | import java.util.Arrays; 14 | import java.util.List; 15 | 16 | /** 17 | * @Author: Silvery 18 | * @Date: 2023/7/5 15:55 19 | */ 20 | @RestController 21 | @RequestMapping("/bank") 22 | public class BankController { 23 | 24 | private Integer processesNumber; // 进程数 25 | private Integer assetsNumber; // 资源数 26 | private List assetsList; // 每个资源总数 27 | private List availableList; // 每个资源剩余资源数 28 | private List request; 29 | private int[][] need = new int[100][100]; 30 | private int[][] max = new int[100][100]; 31 | private int[][] allocation = new int[100][100]; 32 | private int processNum; 33 | private List chokeList = new ArrayList<>(); 34 | 35 | @PostMapping("/initNumber") 36 | public RestBean initNumber(@RequestBody InitNumber initNumber) { 37 | processesNumber = initNumber.getProcessesNumber(); 38 | assetsNumber = initNumber.getAssetsNumber(); 39 | if (processesNumber != null && assetsNumber != null) 40 | return new RestBean<>(200, null); 41 | return new RestBean<>(400, "请检查参数是否正确"); 42 | } 43 | 44 | @PostMapping("/initAssets") 45 | public RestBean initAssets(@RequestBody List assetesList) { 46 | this.availableList = assetesList; 47 | return new RestBean<>(200, null); 48 | } 49 | 50 | @PostMapping("/initOtherAndMath") 51 | public RestBean initOtherAndMath(@RequestBody FinalDto finalDto) { 52 | for (int i = 0; i < (finalDto.getNeed().size() / assetsNumber); i++) 53 | for (int j = 0; j < assetsNumber; j++) 54 | need[i][j] = finalDto.getNeed().get(i * assetsNumber + j); 55 | for (int i = 0; i < (finalDto.getMax().size() / assetsNumber); i++) 56 | for (int j = 0; j < assetsNumber; j++) 57 | max[i][j] = finalDto.getMax().get(i * assetsNumber + j); 58 | for (int i = 0; i < (finalDto.getAllocation().size() / assetsNumber); i++) 59 | for (int j = 0; j < assetsNumber; j++) 60 | allocation[i][j] = finalDto.getAllocation().get(i * assetsNumber + j); 61 | assetsList = new ArrayList<>(); 62 | for (int i = 0; i < availableList.size(); i ++) { 63 | int sum = 0; 64 | for (int[] arr : allocation) 65 | sum += arr[i]; 66 | assetsList.add(sum); 67 | } 68 | 69 | return safetyCheck(null, null); 70 | } 71 | 72 | @PostMapping("/addRequest") 73 | public RestBean addRequest(@RequestBody AddRequestDto addRequestDto) { 74 | // 1.获取需要的资源 75 | request = addRequestDto.getRequestList(); 76 | processNum = addRequestDto.getProcessNum(); 77 | 78 | for (int i = 0; i< request.size(); i++) { 79 | // 2.判断有没有超过need 80 | if (request.get(i) > need[processNum][i]) 81 | return new RestBean<>(400, "对不起,系统出错"); 82 | 83 | // 3.判断剩余资源是否充足 第一种阻塞情况 84 | if (request.get(i) > availableList.get(i)) 85 | return new RestBean<>(400, "剩余资源不足会引起进程" + (processNum + 1) + "处于阻塞状态"); 86 | } 87 | 88 | // 4.尝试分配资源 89 | for (int i = 0; i< request.size(); i++) { 90 | need[processNum][i] = need[processNum][i] - request.get(i); 91 | allocation[processNum][i] = allocation[processNum][i] + request.get(i); 92 | availableList.set(i, availableList.get(i) - request.get(i)); 93 | } 94 | 95 | // 执行安全算法 96 | return safetyCheck(processNum, request); //传入进程号和request 97 | } 98 | 99 | @PostMapping("/deleteRequest") 100 | public RestBean deleteRequest(@RequestBody AddRequestDto addRequestDto) { 101 | return null; 102 | } 103 | 104 | @PostMapping("/addPro") 105 | public RestBean addPro(@RequestBody AddRequestDto addRequestDto) { 106 | processNum = addRequestDto.getProcessNum(); 107 | // 检查进程数是否已达到最大值 108 | if (processesNumber >= 100) 109 | return new RestBean(400, "添加失败,进程数已达到最大值"); 110 | 111 | // 检查资源请求列表是否符合需求 112 | List requestList = addRequestDto.getRequestList(); 113 | for (int i = 0; i < assetsNumber; i++) { 114 | if (requestList.get(i) > assetsList.get(i)) 115 | return new RestBean(400, "添加失败,资源请求数超过资源总数"); 116 | if (requestList.get(i) > availableList.get(i)) 117 | return new RestBean(400, "添加失败,资源请求数超过当前可用资源数"); 118 | } 119 | 120 | // 创建新线程 121 | for (int i = 0; i < assetsNumber; i++) { 122 | max[processNum][i] = requestList.get(i); 123 | allocation[processNum][i] = 0; 124 | need[processNum][i] = requestList.get(i); 125 | availableList.set(i, availableList.get(i) - requestList.get(i)); 126 | } 127 | processesNumber++; 128 | return new RestBean(200, "添加成功"); 129 | } 130 | 131 | public RestBean safetyCheck(Integer process, List request) { 132 | 133 | // 检查是否存在超出资源数量的最大需求 134 | for (int i = 0; i < processesNumber; i++) 135 | for (int j = 0; j < assetsNumber; j++) 136 | if (max[i][j] > assetsList.get(j)) 137 | return new RestBean<>(400, "进程 " + (i + 1) + " 的最大需求超过了资源 " + (j + 1) + " 的总数"); 138 | 139 | // 检查是否存在超出最大需求的分配情况 140 | for (int i = 0; i < processesNumber; i++) 141 | for (int j = 0; j < assetsNumber; j++) 142 | if (allocation[i][j] > max[i][j]) 143 | return new RestBean<>(400, "进程 " + (i + 1) + " 的资源 " + (j + 1) + " 分配超过了最大需求"); 144 | 145 | 146 | // 检查是否存在超出资源数量的需求和分配情况 147 | for (int i = 0; i < processesNumber; i++) 148 | for (int j = 0; j < assetsNumber; j++) 149 | if (need[i][j] > assetsList.get(j) || allocation[i][j] > assetsList.get(j)) 150 | return new RestBean<>(400, "进程 " + (i + 1) + " 的需求或分配超过了资源 " + (j + 1) + " 的总数"); 151 | 152 | 153 | // 检查是否所有资源都已经初始化 154 | if (assetsList.contains(null)) 155 | return new RestBean<>(400, "请初始化所有资源"); 156 | 157 | // 检查是否存在阻塞的进程 158 | for(int i = 0; i < processesNumber; i++) { 159 | // 检查进程是否满足需求 160 | boolean isSafe = true; 161 | for (int j = 0; j < assetsNumber; j++) { 162 | if (need[i][j] > assetsList.get(j)) { 163 | isSafe = false; 164 | break; 165 | } 166 | } 167 | if (!isSafe) 168 | return new RestBean<>(400, "进程 " + (i + 1) + " 阻塞"); 169 | } 170 | 171 | int[] work = new int[assetsNumber]; 172 | boolean[] finish = new boolean[processesNumber]; 173 | List safeSeq = new ArrayList<>(); 174 | 175 | // 初始化work为available 176 | for (int i = 0; i < assetsNumber; i++) { 177 | work[i] = availableList.get(i); 178 | } 179 | 180 | // 初始化完成状态 181 | for (int i = 0; i < processesNumber; i++) 182 | finish[i] = false; 183 | 184 | int count = 0; // 计数器 185 | 186 | // 遍历所有进程 187 | while (count < processesNumber) { 188 | boolean found = false; 189 | for (int i = 0; i < processesNumber; i++) { 190 | if (!finish[i]) { 191 | boolean canExecute = true; 192 | for (int j = 0; j < assetsNumber; j++) { 193 | if (need[i][j] > work[j]) { 194 | canExecute = false; 195 | break; 196 | } 197 | } 198 | if (canExecute) { 199 | for (int j = 0; j < assetsNumber; j++) { 200 | work[j] += allocation[i][j]; 201 | } 202 | safeSeq.add(i); 203 | finish[i] = true; 204 | found = true; 205 | count++; 206 | } 207 | } 208 | } 209 | 210 | // 没有找到可以执行的进程,说明系统处于不安全状态 211 | if (!found) { 212 | safeSeq.clear(); 213 | break; 214 | } 215 | } 216 | if (safeSeq.isEmpty()) { 217 | if (process == null) { 218 | return new RestBean<>(201, "系统处于不安全状态"); 219 | } 220 | else { 221 | // 7. 不安全,则阻塞,第二种阻塞情况 222 | // 回滚数据 223 | for (int i = 0; i< request.size(); i++) { 224 | need[processNum][i] = need[processNum][i] + request.get(i); 225 | allocation[processNum][i] = allocation[processNum][i] - request.get(i); 226 | availableList.set(i, availableList.get(i) + request.get(i)); 227 | } 228 | String str = "进程" + (process + 1) + "处于阻塞状态"; 229 | return new RestBean<>(400, "系统处于不安全状态," + str); 230 | } 231 | } else { 232 | // 6. 安全, 正式分配 233 | return new RestBean<>(200, safeSeq); 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /src/main/resources/static/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 银行家算法模拟系统 7 | 8 | 370 | 371 | 372 | 373 |
374 | 请输入进程数: 375 |
376 | 请输入资源数: 377 |
378 | 381 |

382 |
383 |
384 |

385 |
386 | 389 | 392 | 395 | 398 |
399 | 400 |

401 |

402 | 429 |
430 | 431 | --------------------------------------------------------------------------------